Skip to content

Instantly share code, notes, and snippets.

@JKCooper2
Last active September 19, 2017 00:33
Show Gist options
  • Save JKCooper2/87d1cbc41684a396d39543eb413476ef to your computer and use it in GitHub Desktop.
Save JKCooper2/87d1cbc41684a396d39543eb413476ef to your computer and use it in GitHub Desktop.
APEX sObject sObjectHasProperty, sObjectHasPath, getSObjectPath (including default)
/*
Provides utility functions for checking/accessing sObject properties
Updates:
- Namespace no longer required
- Replaced getPopulatedFieldsAsMap() with a plain try catch to improve speed
- Allowed for returns of SObjects
- Throw out SObjectException where the field exists but wasn't queried
To Do:
- Should the throw nonqueried fields be a flag
- Find out if it's possible for support children like 'child__r[0].grandchild__r[0]'
Cases supported:
Id testId = (Id)Utility.getSObjectPath(so, 'Parent__r.GrandParent__r.IDField');
Boolean hasField = Utility.sObjectHasPath(so, 'Parent__r.GrandParent__r.IDField');
Id defaultTestId = (Id)Utility.getSObjectPath(so, 'Parent__r.GrandParent__r.IDField', defaultId);
Grandparent__c grandparent = (Grandparent__c)Utility.getSObjectPath(so, 'Parent__r.GrandParent__r');
Running speed ~ 10-20K calls/second
For comparison try { testId = so.Parent__r.GrandParent__r.IDField } catch() { testId = defaultId } ~ 50-100K calls/second
*/
public static Boolean sObjectHasProperty(SObject so, String fieldName) {
return Utility.sObjectHasPath(so, fieldName);
}
public static Boolean sObjectHasPath(SObject so, String fieldPath) {
return Utility.getSObjectPath(so, fieldPath) != null;
}
public static Object getSObjectPath(SObject so, String fieldPath) {
if(so == null || String.isBlank(fieldPath)) {
return null;
}
List<String> fields = fieldPath.split('\\.');
//All fields up to the last must be a relationship field;
for(Integer i = 0; i < fields.size() - 1; i++) {
if(fields[i].right(3) != '__r') {
return null;
}
}
for(Integer i = 0; i < fields.size(); i++) {
if(i < fields.size() - 1) {
try {
so = so.getSObject(fields[i]);
} catch(SObjectException ex) {
//If error is field wasn't queried then rethrow
if(ex.getMessage().contains('SObject row was retrieved via SOQL without querying the requested field')) {
throw ex;
}
//Else field is invalid
return null;
} catch(Exception ex) {
return null;
}
} else {
try {
//Return another sObject
if(fields[i].right(3) == '__r') {
return so.getSobject(fields[i]);
} else { //Else return the object
return so.get(fields[i]);
}
} catch(SObjectException ex) {
//If error is field wasn't queried then rethrow
if(ex.getMessage().contains('SObject row was retrieved via SOQL without querying the requested field')) {
throw ex;
}
//Else field is invalid
return null;
} catch(Exception ex) {
return null;
}
}
}
return null;
}
public static Object getSObjectPath(SObject so, String fieldPath, Object defaultValue) {
Object ob = Utility.getSObjectPath(so, fieldPath);
return ob != null ? ob : defaultValue;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment