I need to update the Picklist values for a custom field on a custom object. I have already populated the Available Values via the Enterprise and Metadata Java APIs, but now I need to move the newly updated Available Values to the Selected Values Picklist.
I can query the custom field as described in this post:
REST API: How to retrieve active values for picklist?
Does anyone have an example of doing this via the Enterprise/Metadata APIs?
Update:
This is the code that I use to update the picklist using the Salesforce API. This only updates the Available Values and not the Selected Values of the Picklist:
/** Updates the versions in Salesforce. */
public void updateSalesforceVersions() throws ConnectionException, InterruptedException
{
// Salesforce object and field name values
String sObjectName = "Product_Information__c";
String fieldName = "Licensed_Version__c";
String fullName = String.format("%s.%s", sObjectName, fieldName);
List<OhmVersion> versionsFromDao = this.getOhmVersions();
Field versionsField = SalesforceUtilities.getField(
salesforceConnectionSource.getConnection().getEnterpriseConnection(),
FieldType.picklist, sObjectName, fieldName);
if(versionsField == null)
return;
Picklist versionsPicklist = new Picklist();
List<PicklistValue> versionsPicklistValues = new ArrayList<>();
for (OhmVersion version : versionsFromDao)
{
PicklistValue picklistValue = new PicklistValue();
picklistValue.setFullName(version.getVersion());
versionsPicklistValues.add(picklistValue);
}
versionsPicklist.setPicklistValues(versionsPicklistValues.toArray(
new PicklistValue[versionsPicklistValues.size()]));
CustomField customField = new CustomField();
customField.setFullName(fullName);
customField.setType(com.sforce.soap.metadata.FieldType.Picklist);
customField.setLabel(versionsField.getLabel());
customField.setPicklist(versionsPicklist);
AsyncResult asyncResult = SalesforceUtilities.updateCustomField(
salesforceConnectionSource.getConnection().getMetadataConnection(),
fullName, customField);
}
This is the code that actually updates the picklist metadata:
public static AsyncResult updateCustomField(MetadataConnection metadataConnection,
String fullName,
CustomField customField)
throws ConnectionException, InterruptedException
{
AsyncResult asyncResult = new AsyncResult();
// do the update
UpdateMetadata updateMetadata = new UpdateMetadata();
updateMetadata.setMetadata(customField);
updateMetadata.setCurrentName(fullName);
// wait for it to complete
AsyncResult[] ars = metadataConnection.update(new UpdateMetadata[] {
updateMetadata });
asyncResult = ars[0];
// set initial wait time to one second
long waitTimeMilliSecs = 1000;
while(!asyncResult.isDone())
{
Thread.sleep(waitTimeMilliSecs);
// double the wait time for the next iteration
waitTimeMilliSecs *= 2;
asyncResult = metadataConnection.checkStatus(new String[] { asyncResult.getId()})[0];
}
return asyncResult;
}
This only updates the Available Values. I don't see any method or property to update the Selected Values. I can query the Selected Values with this code by using the EnterpriseConnection.describeLayout()
method:
public void describeLayout()
{
String sObjectName = PRODUCT_INFORMATION;
try
{
// Make the describe call
DescribeLayoutResult describeLayoutResult =
this.enterpriseConnection.describeLayout(sObjectName,
new String[] { SalesforceConstants.PRODUCT_INFORMATION_OHM_RECORD_TYPE_ID });
// Get sObject metadata
if (describeLayoutResult != null)
{
for(RecordTypeMapping recordTypeMapping : describeLayoutResult.getRecordTypeMappings())
{
System.out.println("RecordTypeMap name: " + recordTypeMapping.getName());
for(PicklistForRecordType picklistForRecordType : recordTypeMapping.getPicklistsForRecordType())
{
System.out.println("Picklist Name:" + picklistForRecordType.getPicklistName());
for(PicklistEntry entry : picklistForRecordType.getPicklistValues())
{
System.out.println("Entry Value:" + entry.getValue());
}
System.out.println();
}
System.out.println();
}
}
}
catch (ConnectionException ce)
{
fail("Connection failed: " + ce);
}
}
How do I update the Selected Values even if I need to use a different class/method?
Best Answer
I was finally able to figure it out. It was a combination of using the RecordType with the metadata.update() call: