/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.sa.descriptor; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import org.apache.commons.lang.StringUtils; public class ServiceDescriptorBuilder { public static final String CATEGORY_SUFFIX = ".category"; public static final String TITLE_SUFFIX = ".title"; public static final String LABEL_SUFFIX = ".label"; public static final String DESCRIPTION_SUFFIX = ".description"; public static final String ERROR_SUFFIX = ".validation.error"; private List<ResourceBundle> bundles; public ServiceDescriptorBuilder(String... bundleNames) { this(ServiceDescriptorBuilder.class.getClassLoader(), Locale.getDefault(), bundleNames); } public ServiceDescriptorBuilder(ClassLoader loader, Locale locale, String... bundleNames) { bundles = new ArrayList<>(); for (int i = 0; i < bundleNames.length; i++) { bundles.add(ResourceBundle.getBundle(bundleNames[i], locale, loader)); } } public ServiceDescriptor build(ServiceDefinition definition) { String baseKey = StringUtils.defaultIfBlank(definition.baseKey, definition.serviceId); ServiceDescriptor service = new ServiceDescriptor(); service.setServiceId(definition.serviceId); service.setCategory(getMessage(definition.categoryKey, baseKey + CATEGORY_SUFFIX)); service.setTitle(getMessage(definition.titleKey, baseKey + TITLE_SUFFIX)); service.setDescription(getMessage(definition.descriptionKey, baseKey + DESCRIPTION_SUFFIX)); service.addRoles(definition.roles); service.setUseModal(definition.useModal); service.setModalTitle(definition.modalTitle); // Ensure that a missing resource keys don't cause the service to be hidden in the catalog if (StringUtils.isBlank(service.getTitle())) { service.setTitle(StringUtils.defaultString(definition.titleKey, definition.serviceId)); } for (ItemDefinition itemDefinition : definition.items.values()) { ServiceItem item = build(baseKey, itemDefinition); service.addItem(item); } return service; } public ServiceItem build(String baseKey, ItemDefinition definition) { if (StringUtils.equals(definition.type, ServiceItem.TYPE_GROUP)) { return build(baseKey, (GroupDefinition) definition); } else if (StringUtils.equals(definition.type, ServiceItem.TYPE_TABLE)) { return build(baseKey, (TableDefinition) definition); } else if (StringUtils.equals(definition.type, ServiceItem.TYPE_MODAL)) { return build(baseKey, (ModalDefinition) definition); } else { return build(baseKey, (FieldDefinition) definition); } } public ServiceField build(String baseKey, FieldDefinition definition) { String baseFieldKey = getBaseKey(baseKey, definition); ServiceField field = new ServiceField(); apply(baseFieldKey, definition, field); field.setRequired(definition.required); field.setOmitNone(definition.omitNone); field.setLockable(definition.lockable); field.setInitialValue(definition.initialValue); field.setModalField(definition.modalField); field.setSelect(definition.select); field.addOptions(definition.options); field.getValidation().setMin(definition.validation.min); field.getValidation().setMax(definition.validation.max); field.getValidation().setRegEx(definition.validation.regEx); field.getValidation().setError(getMessage(definition.validation.errorKey, baseFieldKey + ERROR_SUFFIX)); return field; } public ServiceFieldGroup build(String baseKey, GroupDefinition definition) { String baseGroupKey = getBaseKey(baseKey, definition); ServiceFieldGroup group = new ServiceFieldGroup(); apply(baseGroupKey, definition, group); group.setCollapsible(definition.collapsible); group.setCollapsed(definition.collapsed); for (ItemDefinition itemDefinition : definition.items.values()) { ServiceItem item = build(baseGroupKey, itemDefinition); group.addItem(item); } return group; } public ServiceFieldTable build(String baseKey, TableDefinition definition) { String baseTableKey = getBaseKey(baseKey, definition); ServiceFieldTable table = new ServiceFieldTable(); apply(baseTableKey, definition, table); for (FieldDefinition fieldDefinition : definition.fields.values()) { ServiceField field = build(baseTableKey, fieldDefinition); table.addItem(field); } return table; } public ServiceFieldModal build(String baseKey, ModalDefinition definition) { String baseTableKey = getBaseKey(baseKey, definition); ServiceFieldModal modal = new ServiceFieldModal(); apply(baseTableKey, definition, modal); for (ItemDefinition itemDefinition : definition.items.values()) { ServiceItem item = build(baseTableKey, itemDefinition); modal.addItem(item); } return modal; } private void apply(String baseKey, ItemDefinition source, ServiceItem target) { target.setName(source.name); target.setType(source.type); target.setLabel(getMessage(source.labelKey, baseKey + LABEL_SUFFIX)); target.setDescription(getMessage(source.descriptionKey, baseKey + DESCRIPTION_SUFFIX)); // Use the field name if no label is found if (StringUtils.isBlank(target.getLabel())) { target.setLabel(source.name); } } private String getBaseKey(String baseKey, ItemDefinition definition) { return String.format("%s.%s", baseKey, definition.name); } private String getMessage(String key, String defaultKey) { String message = getMessage(key); if (message != null) { return message; } else { return getMessage(defaultKey); } } /** * Finds a message within the resource bundles based on the key. This will try to locate the most specific match in * all bundles before shortening the key and looking for a more generic version. The key is dot-separated, each pass * will test the key value against all resource bundles. If no match is found, the leading value is removed and it * is retried until the key is empty or a match is found. * * @param key * the key to find. * @return the message, or null if no match is found. */ private String getMessage(String key) { while (StringUtils.isNotBlank(key)) { for (ResourceBundle bundle : bundles) { String message = getMessage(bundle, key); if (message != null) { return message; } } key = StringUtils.substringAfter(key, "."); } return null; } /** * Gets a message from a resource bundle, returning null if no key is found. * * @param bundle * the resource bundle. * @param key * the message key. * @return the message. */ private static String getMessage(ResourceBundle bundle, String key) { try { return bundle.getString(key); } catch (MissingResourceException e) { return null; } } }