5

We have a scenario where we need to make assignments to fields using the method put(String, Object)

Ref: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_sobject.htm#apex_System_SObject_put

Once in a managed package the assignment:

String oldDesc = (String)acc.put('Custom_Field__c', 'some value');

will fail, because the packaged field will have a namespace prefix. So if it's been packaged as

`mypackage`

, the correct put() call would be:

String oldDesc = (String)acc.put('mypackage__Custom_Field__c', 'some value');

How can I avoid hard coding a package namespace?

3

I can suggest getting the namespace from the current class name..

public String getNamespacePrefix() {
    String namespacePrefix;
    String[] classNameParts = String.valueOf(<Enter className>.class).split('\\.', 2);
    if(classNameParts.size() > 1) {
        Type classType = Type.forName(classNameParts[0], classNameParts[1]);
        if(classType == <Enter className>.class) {
            namespacePrefix = classNameParts[0];
        } else {
            namespacePrefix = '';
        }
    } else {
        //If there is only one part, the class has no namespace
        namespacePrefix = '';
    }
    return namespacePrefix; 
}
  • 2
    If you're going to call this method frequently, it might be worth making it static, putting it in a utility class, and having it cache the result for subsequent calls. – Mr. DOS Jun 4 '15 at 17:09
  • 1
    Yes, I agree. This is just an example. If you are going to use this, do as Mr.DOS has suggested. – navD87 Jun 4 '15 at 17:12
  • 1
    @bananka If I'm going to put the method in a utility class anyway, I'd add a static field to that class (private static String namespacePrefix = null;). At the top of the getNamespacePrefix() method, I'd check to see if that field was non-null, and if so, I'd return it. Otherwise, I'd go through the process of determining the namespace prefix, but right before returning, I'd set the value of the static field. – Mr. DOS Jun 5 '15 at 14:55
  • 2
    @bananka I've written an example of this pattern. Hopefully this will clear up what I'm suggesting. – Mr. DOS Jun 5 '15 at 17:44
  • 1
    @Mr.DOS thanks for the sample. This cache is only alive until the page is closed and the apex transaction ends, isn't it? I guess it could be more useful in java or c#. – bananka Jun 8 '15 at 11:29
3

If the logic is in a class known to not be an inner class then the logic can be simpler:

public class Utils {
    // Return the namespace prefix or an empty string if there isn't one
    public static String namespacePrefix {
        get {
            if (namespacePrefix == null) {
                String[] parts = String.valueOf(Utils.class).split('\\.', 2);
                namespacePrefix = parts.size() == 2 ? parts[0] : '';
            }
            return namespacePrefix;
        }
        private set;
    }
}
1

Can you not try like this without doing any extra efforts? If you know any custom field or custom object of your managed package then the following solution should work.

If you have a custom object with Custom_Object__c API Name

Schema.DescribeSObjectResult dsr = Custom_Object__c.sObjectType.getDescribe();
String namespacePrefix = dsr.getName().remove(dsr.getLocalName());

If you have a custom field with Custom_Field__c API Name

Schema.DescribeFieldResult dfr = Account.sObjectType.fields.Custom_Field__c.getDescribe();
String namespacePrefix = dfr.getName().remove(dfr.getLocalName());

I think this way you don't need to do any query on Apex class. Doing a query or using an apex class may lead you in a wrong path as there could be 2 managed packages with the same class name but there won't be a problem with 2 fields with the same API name since it will pick the managed package field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.