The type-safe identifiers the MetadataConstantsParser task generates are specifically constants that encapsulate the propName and expected value class of some FieldMetadata. Because a DynamicLookupListFieldMetadata’s value class is String, the generated identifier should be String. The main reason they exist isn’t to provide extra info about that FieldMetadata, such as what are the possible values of a LookupList field or Dynamic LookupList field, but rather a type-safe way to put values into a DataObject and to get them back out.
For example, if my LookupList field: state should determine the choices for my Dynamic LookupList field: city, then I could use the type-safe identifiers like this to set DataObject values for these fields and to access them.
DataObject person = DataObject.newBuilder()
.withType(PersonMetadataConstants.TYPE)
.with(PersonMetadataConstants.STATE, "NY")
.with(PersonMetadataConstants.CITY, "New York City")
.build();
String state = person.get(PersonMetadataConstants.STATE);
String city = person.get(PersonMetadataConstants.CITY);
// The following wouldn't compile, hence the name type-safe identifiers:
// int state = person.get(PersonMetadataConstants.STATE);
// and that's because STATE is a "String"FieldIdentifier not an "Integer" one.
See more about type-safe identifiers on this Knowledge Base article.
Programmatically if you need a way to find out what choices a user has available to them given the state they’ve picked, you could do something like this:
var context = Context.makeSystemContext();
var metadataService = dataService.getMetadataService();
BeanMetadata personBeanMetadata = getOnlyElement(metadataService.loadLatestBeanMetadataEditions(List.of("Person"), context));
var state = person.get(PersonMetadataConstants.STATE);
var cityFieldMetadata = (DynamicLookupListFieldMetadata) personBeanMetadata.getField("city");
NameAndEdition subListNameAndEdition = cityFieldMetadata.getSubLists()
.stream()
.filter(subList -> state.equals(subList.getParentListValue()))
.collect(MoreCollectors.onlyElement())
.getSubListNameAndEdition();
LookupList lookupList = getOnlyElement(dataService.getLookupListService()
.loadByNameAndEditions(List.of(subListNameAndEdition), context));
List<String> possibleValues = lookupList.getItems()
.stream()
.map(LookupListItem::getValue)
.collect(Collectors.toList());
And of course that’s a fair bit of code for that field, but the main use case is to populate dropdown menus in the UI, and the LEAF JS component for rendering the dropdown menu handles all of that logic for you.
All of that said, there is also another generated file for constants for LookupLists that includes their names and values. So you could certainly leverage it too. So if your States LookupList has values NY, PA, WV, etc., you would see a generated file like this somewhere:
public final class States_LookupListConstants {
private States_LookupListConstants() {}
// Name Constant
public static final String NAME = "States";
// Item Value Constants
public static final String NY = "NY";
public static final String PA = "PA";
public static final String WV = "WV";
// Constants Set
public static final Set<String> VALUES = ImmutableSet.<String> builder()
.add(NY)
.add(PA)
.add(WV)
.build();
}
And of course you could write simple if-statements to mimic the logic above, like:
Set<String> possibleValues;
if (state.equals(States_LookupListConstants.NY)) {
possibleValues = NYCities_LookupListConstants.VALUES;
}
// etc.
Note that the metadata Gradle plugin didn’t start generating LookupListConstants files until 3.5, but the LookupListConstantsParser can be manually wired up on earlier versions. There should be a KB page on how to do that.