if (result != null) {
return result;
}
result = Maps.newHashMap();
ContentItemTypesBundle globalBundle = new ContentItemTypesBundle("");
result.put(null, globalBundle);
// put an entry in the map for each theme, too. Since some themes may have no content items,
// we should do this up-front, not lazily.
for (Theme theme : getThemesForLivingStory(livingStoryId)) {
result.put(theme.getId(), new ContentItemTypesBundle(theme.getName()));
}
// In principle, we could try to track when we've found every content item type that we care
// about, in every possible theme, terminating the loop early if our dance card is completely
// filled, but it's such a micro-optimization at this point that it's not worthwhile.
List<BaseContentItem> allContentItems =
contentRpcService.getContentItemsForLivingStory(livingStoryId, true);
for (BaseContentItem contentItem : allContentItems) {
if (!addContentItemToTypesBundle(contentItem, globalBundle)) {
continue;
}
for (Long themeId : contentItem.getThemeIds()) {
ContentItemTypesBundle themeBundle = result.get(themeId);
if (themeBundle == null) {
logger.warning("contentItem " + contentItem.getId() + " refers to themeId " + themeId
+ ", but this theme does not appear to be in the story.");
} else {
addContentItemToTypesBundle(contentItem, themeBundle);