Class FormBuilderServiceImpl

java.lang.Object
org.broadleafcommerce.openadmin.web.service.FormBuilderServiceImpl
All Implemented Interfaces:
FormBuilderService

@Service("blFormBuilderService") public class FormBuilderServiceImpl extends Object implements FormBuilderService
Author:
Andre Azzolini (apazzolini)
  • Field Details

    • ALTERNATE_ID_PROPERTY

      public static final String ALTERNATE_ID_PROPERTY
      See Also:
    • GRID_HIDDEN_VISIBILITIES

      public static final org.broadleafcommerce.common.presentation.client.VisibilityEnum[] GRID_HIDDEN_VISIBILITIES
    • FORM_HIDDEN_VISIBILITIES

      protected static final org.broadleafcommerce.common.presentation.client.VisibilityEnum[] FORM_HIDDEN_VISIBILITIES
    • adminEntityService

      protected AdminEntityService adminEntityService
    • extensionManager

      protected FormBuilderExtensionManager extensionManager
    • entityConfiguration

      protected org.broadleafcommerce.common.persistence.EntityConfiguration entityConfiguration
    • adminRemoteSecurityService

      protected SecurityVerifier adminRemoteSecurityService
    • rowLevelSecurityService

      protected RowLevelSecurityService rowLevelSecurityService
    • mediaBuilderService

      protected MediaBuilderService mediaBuilderService
    • listGridErrorExtensionManager

      protected ListGridErrorMessageExtensionManager listGridErrorExtensionManager
    • adminNavigationService

      protected AdminNavigationService adminNavigationService
    • duplicator

      protected org.broadleafcommerce.common.persistence.EntityDuplicator duplicator
    • dynamicEntityDao

      protected DynamicEntityDao dynamicEntityDao
    • localeService

      protected org.broadleafcommerce.common.locale.service.LocaleService localeService
    • translationService

      protected org.broadleafcommerce.common.i18n.service.TranslationService translationService
    • useTranslationSearch

      @Value("${use.translation.search:false}") protected boolean useTranslationSearch
    • exploitProtectionService

      protected org.broadleafcommerce.common.security.service.ExploitProtectionService exploitProtectionService
  • Constructor Details

    • FormBuilderServiceImpl

      public FormBuilderServiceImpl()
  • Method Details

    • buildMainListGrid

      public ListGrid buildMainListGrid(DynamicResultSet drs, ClassMetadata cmd, String sectionKey, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Builds a list grid that is typically used at the top entity level to select an entity for modification.

      Note that it can also be used in other places that require the same grid as the main entity search screen provided the type on the returned ListGrid is set appropriately.

      Specified by:
      buildMainListGrid in interface FormBuilderService
      Returns:
      the ListGrid
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • getTranslationSearchField

      protected void getTranslationSearchField(String ceilingEntity, ArrayList<FieldDTO> defaultWrapperFields)
    • constructFieldDTOFromFieldData

      protected FieldDTO constructFieldDTOFromFieldData(Field field, BasicFieldMetadata fmd)
    • createHeaderField

      protected Field createHeaderField(Property p, BasicFieldMetadata fmd)
    • initHeaderField

      protected Field initHeaderField(BasicFieldMetadata fmd)
    • isComboField

      protected boolean isComboField(BasicFieldMetadata fmd)
    • isSupportedFieldTypes

      protected boolean isSupportedFieldTypes(BasicFieldMetadata fmd, org.broadleafcommerce.common.presentation.client.SupportedFieldType... supportedFieldType)
    • buildCollectionListGrid

      public ListGrid buildCollectionListGrid(String containingEntityId, DynamicResultSet drs, Property field, String sectionKey, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Builds a list grid that is used to render a collection inline in an entity form.

      Note that it can also be used in other places that require the same grid provided the type on the returned ListGrid is set appropriately.

      Specified by:
      buildCollectionListGrid in interface FormBuilderService
      Returns:
      the ListGrid
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • propertyExistsInResultSet

      protected boolean propertyExistsInResultSet(Property property, DynamicResultSet drs)
    • getMapKeyFriendlyName

      protected String getMapKeyFriendlyName(Property property)
    • buildSelectizeCollectionInfo

      public Map<String,Object> buildSelectizeCollectionInfo(String containingEntityId, DynamicResultSet drs, Property field, String sectionKey, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Specified by:
      buildSelectizeCollectionInfo in interface FormBuilderService
      Returns:
      the ListGrid
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • constructSelectizeOptionMap

      public Map<String,Object> constructSelectizeOptionMap(DynamicResultSet drs, ClassMetadata cmd)
      Description copied from interface: FormBuilderService
      constructs the selectize option map based on the dynamic result set and class metadata
      Specified by:
      constructSelectizeOptionMap in interface FormBuilderService
      Returns:
    • buildSelectizeUrl

      protected String buildSelectizeUrl(ListGrid listGrid)
    • createListGrid

      @Deprecated protected ListGrid createListGrid(String className, List<Field> headerFields, ListGrid.Type type, DynamicResultSet drs, String sectionKey, int order, String idProperty, List<SectionCrumb> sectionCrumbs)
      Parameters:
      className -
      headerFields -
      type -
      drs -
      sectionKey -
      order -
      idProperty -
      sectionCrumbs -
      Returns:
    • createListGrid

      protected ListGrid createListGrid(String className, List<Field> headerFields, ListGrid.Type type, DynamicResultSet drs, String sectionKey, Integer order, String idProperty, List<SectionCrumb> sectionCrumbs, String sortPropery)
      Populate a ListGrid with ListGridRecords.
      Parameters:
      className -
      headerFields -
      type -
      drs -
      sectionKey -
      order -
      idProperty -
      sectionCrumbs -
      sortPropery -
      Returns:
    • isDerivedField

      protected Boolean isDerivedField(Field headerField, Field recordField, Property p)
      Determines whether or not a particular field in a record is derived. By default this checks the BasicFieldMetadata for the given Property to see if something on the backend has marked it as derived
      Parameters:
      headerField - the header for this recordField
      recordField - the recordField being populated
      p - the property that relates to this recordField
      Returns:
      whether or not this field is derived
    • setEntityFormFields

      protected void setEntityFormFields(ClassMetadata cmd, EntityForm ef, List<Property> properties)
    • setDateToRecordField

      protected void setDateToRecordField(Field recordField, Property property, SimpleDateFormat formatter)
    • getFieldComponentRenderer

      protected String getFieldComponentRenderer(BasicFieldMetadata fmd)
    • getGridFieldComponentRenderer

      protected String getGridFieldComponentRenderer(BasicFieldMetadata fmd)
    • getAdminSectionPath

      protected String getAdminSectionPath(String foreignKeyClass)
      This method gets the AdminSection for the given foreignKeyClass parameter. If none exists, it returns the foreignKeyClass.
      Parameters:
      foreignKeyClass - the String class name
      Returns:
      the admin section pathname
    • setEntityFormTabsAndGroups

      protected void setEntityFormTabsAndGroups(EntityForm ef, Map<String,TabMetadata> tabMetadataMap)
      NOTE: This method will attempt to merge tabs if the unprocessed TabMetadata.getTabName() is equal to the processed value of another tab.

      For example, if TabMetadata.getTabName() is "Example", there is a another tab where TabMetadata.getTabName() is "Example_Tab", and a message property where 'Example_Tab=Example', then the tabs should be merged together, so that we do not end up rendering multiple "Example" tabs.

    • getUnprocessedNameOfMatchingTab

      protected String getUnprocessedNameOfMatchingTab(TabMetadata tabMetadata, Set<String> tabMetadataKeySet)
      Search for any other tab on the target entity that has the same display value as the value provided tab name.

      This assumes that the TabMetadata.getTabName() is in the form of a processed message property. For example, if TabMetadata.getTabName() is "Example", there is a tabKey from the tabMetadataKeySet that is "Example_Tab", and a message property where 'Example_Tab=Example', then this method should return "Example_Tab" which will end up causing the tabs to merge together.

      If a tab with the same display value cannot be found, then we should return null to indicate that there is no matching tab with the same processed tabName value.

    • processedTabKeyMatchesTabName

      protected boolean processedTabKeyMatchesTabName(String tabName, String candidateTabKey)
    • foundMatchingTab

      protected boolean foundMatchingTab(String unprocessedTabName)
    • tabExists

      protected boolean tabExists(EntityForm ef, String tabKey)
    • extractDefaultValueFromFieldData

      public String extractDefaultValueFromFieldData(String fieldType, BasicFieldMetadata fmd)
      Description copied from interface: FormBuilderService
      Extracts the DefaultValue from the FieldMetaData and parses it based on the SupportedFieldType that the field uses.

      Logs a warning in the event of failure to parse the value and returns null.

      Specified by:
      extractDefaultValueFromFieldData in interface FormBuilderService
      Returns:
      The value to be used on the form field.
    • buildMsgForDefValException

      protected String buildMsgForDefValException(String type, BasicFieldMetadata fmd, String defaultValue)
    • removeNonApplicableFields

      public void removeNonApplicableFields(ClassMetadata cmd, EntityForm entityForm, String entityType)
      Description copied from interface: FormBuilderService
      Loops through all of the fields that are specified in given class metadata and removes fields that are not applicable for the given polymorphic entity type from the entity form.
      Specified by:
      removeNonApplicableFields in interface FormBuilderService
    • createEntityForm

      public EntityForm createEntityForm(ClassMetadata cmd, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Creates a new EntityForm with the a default 'Save' action. This will then delegate to #populateEntityForm(ClassMetadata, EntityForm) to ensure that the newly created EntityForm has all of the appropriate fields set up without any values based on cmd
      Specified by:
      createEntityForm in interface FormBuilderService
      Returns:
      the EntityForm
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • extractSectionIdentifierFromCrumb

      protected String extractSectionIdentifierFromCrumb(List<SectionCrumb> sectionCrumbs)
    • populateEntityForm

      public void populateEntityForm(ClassMetadata cmd, EntityForm ef, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Populates the given ef with all of the fields based on the properties from cmd. For all the fields that are created, no values are set (as cmd usually does not have any). In order to fill out values in the given ef, consider instead calling #populateEntityForm(ClassMetadata, Entity, EntityForm, boolean)
      Specified by:
      populateEntityForm in interface FormBuilderService
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • addAdditionalFormActions

      protected void addAdditionalFormActions(EntityForm ef)
      This method is invoked when EntityForms are created and is meant to provide a hook to add additional entity form actions for implementors of Broadleaf. Broadleaf modules will typically leverage FormBuilderExtensionHandler.addAdditionalFormActions(EntityForm) method.
      Parameters:
      ef -
    • createEntityForm

      public EntityForm createEntityForm(ClassMetadata cmd, Entity entity, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Creates a new EntityForm that has all of the appropriate fields set up along with the values for those fields from the given Entity. Delegates to #createEntityForm(ClassMetadata) for further population
      Specified by:
      createEntityForm in interface FormBuilderService
      Parameters:
      cmd - metadata that the created EntityForm should use to initialize its fields
      Returns:
      the EntityForm
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • populateEntityForm

      public void populateEntityForm(ClassMetadata cmd, Entity entity, EntityForm ef, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Populates a given ef based on the given cmd to initially create fields with the necessary metadata and then fills those fields out based on the property values from entity.
      Specified by:
      populateEntityForm in interface FormBuilderService
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • setVisibilityBasedOnShowIfFieldEquals

      protected void setVisibilityBasedOnShowIfFieldEquals(ClassMetadata cmd, Entity entity, EntityForm ef)
    • shouldHideField

      protected boolean shouldHideField(FieldMetadata fmd, Entity entity)
    • populateEntityFormFieldValues

      public void populateEntityFormFieldValues(ClassMetadata cmd, Entity entity, EntityForm ef)
      Description copied from interface: FormBuilderService
      Populates the given EntityForm with values based on the Entity that has been passed in. The ClassMetadata is used to determine which properties should be attempted to be populated
      Specified by:
      populateEntityFormFieldValues in interface FormBuilderService
      Parameters:
      cmd - 'inspect' metadata for the class being populated
      entity - the Entity that should be used to fill out the field values in the given EntityForm
      ef - the EntityForm to populate field values from the given Entity
    • decodeValueIfNeeded

      protected String decodeValueIfNeeded(BasicFieldMetadata basicFM, String value)
    • convertJsonToDataWrapper

      protected DataWrapper convertJsonToDataWrapper(String json)
      When using Thymeleaf, we need to convert the JSON string back to a DataWrapper object because Thymeleaf escapes JSON strings. Thymeleaf uses it's own object de-serializer see: https://github.com/thymeleaf/thymeleaf/issues/84 see: http://forum.thymeleaf.org/Spring-Javascript-and-escaped-JSON-td4024739.html
      Parameters:
      json -
      Returns:
      DataWrapper
      Throws:
      IOException
    • populateDropdownToOneFields

      protected void populateDropdownToOneFields(EntityForm ef, ClassMetadata cmd) throws org.broadleafcommerce.common.exception.ServiceException
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • createEntityForm

      public EntityForm createEntityForm(ClassMetadata cmd, Entity entity, Map<String,DynamicResultSet> collectionRecords, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Builds an EntityForm that has all of the appropriate fields set up along with the values for those fields from the given Entity as well as all sub-collections of the given Entity that appear in the collectionRecords map. This method simply delegates to create a standard EntityForm (that has a save action) and then populates that EntityForm using #populateEntityForm(ClassMetadata, Entity, Map, EntityForm).

      NOTE: if you are submitting a validation result, you must not call this method and instead invoke the one that has an EntityForm as a parameter. You cannot re-assign the entityForm to the model after it has already been bound to a BindingResult, else the binding result will be removed.

      Specified by:
      createEntityForm in interface FormBuilderService
      Returns:
      the EntityForm
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • populateEntityForm

      public void populateEntityForm(ClassMetadata cmd, Entity entity, Map<String,DynamicResultSet> collectionRecords, EntityForm ef, List<SectionCrumb> sectionCrumbs) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Builds an EntityForm that has all of the appropriate fields set up along with the values for thsoe fields from the given Entity as well as all sub-collections of the given Entity that appear in the collectionRecords map.

      NOTE: This method is mainly used when coming back from validation. In the case of validation, you cannot re-add a new EntityForm to the model or else you lose the whole BindingResult and errors will not properly be displayed. In that scenario, you must use this method rather than the one that does not take in an entityForm as it will attempt to instantiate a new object.

      Specified by:
      populateEntityForm in interface FormBuilderService
      ef - rather than instantiate a new EntityForm, this will use this parameter to fill out
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • addDeleteActionIfAllowed

      protected void addDeleteActionIfAllowed(EntityForm entityForm, ClassMetadata cmd, Entity entity)
      Adds the DefaultEntityFormActions.DELETE if the user is allowed to delete the entity. The user can delete an entity for the following cases:
      1. The user has the security to EntityOperationType.REMOVE the given class name represented by the entityForm (determined by getSecurityClassname(EntityForm, ClassMetadata))
      2. The user has the security necessary to delete the given entity according to the RowLevelSecurityProvider.canRemove(AdminUser, Entity)
      Parameters:
      entityForm - the form being generated
      cmd - the metatadata used to build the entityForm for the entity
      entity - the entity being edited
    • isDeletionAllowed

      protected boolean isDeletionAllowed(EntityForm entityForm, ClassMetadata cmd, Entity entity)
    • addDuplicateActionIfAllowed

      protected void addDuplicateActionIfAllowed(EntityForm entityForm, ClassMetadata cmd)
    • isDuplicationAllowed

      protected boolean isDuplicationAllowed(EntityForm entityForm, ClassMetadata cmd)
    • setReadOnlyState

      protected void setReadOnlyState(EntityForm entityForm, ClassMetadata cmd, Entity entity)
      The given entityForm is marked as readonly for the following cases:
      1. All of the properties from cmd are readonly
      2. The user does not have the security to EntityOperationType.UPDATE the given class name represented by the entityForm (determined by getSecurityClassname(EntityForm, ClassMetadata))
      3. The user does not have the security necessary to modify the given entity according to the RowLevelSecurityProvider.canUpdate(AdminUser, Entity)
      Parameters:
      entityForm - the form being generated
      cmd - the metatadata used to build the entityForm for the entity
      entity - the entity being edited
    • getSecurityClassname

      protected String getSecurityClassname(EntityForm entityForm, ClassMetadata cmd)
      Obtains the class name suitable for passing along to the SecurityVerifier
      Parameters:
      entityForm -
      cmd -
      Returns:
    • populateEntityFormFields

      public void populateEntityFormFields(EntityForm ef, Entity entity)
      Description copied from interface: FormBuilderService
      Delegates to FormBuilderService.populateEntityFormFields(EntityForm, Entity, boolean, boolean) with true for populating both the id and type.
      Specified by:
      populateEntityFormFields in interface FormBuilderService
    • populateEntityFormFields

      public void populateEntityFormFields(EntityForm ef, Entity entity, boolean populateType, boolean populateId)
      Description copied from interface: FormBuilderService
      Sets values for all fields found on the EntityForm from the specified entity.
      Specified by:
      populateEntityFormFields in interface FormBuilderService
      populateType - whether or not to use the type from the given Entity or keep the current value on the EntityForm
      populateId - whether or not to use the id from the given Entity or keep the current value on the EntityForm
    • populateAdornedEntityFormFields

      public void populateAdornedEntityFormFields(EntityForm ef, Entity entity, AdornedTargetList adornedList)
      Description copied from interface: FormBuilderService
      Sets values for the necessary adorned fields on the EntityForm from the specified entity.
      Specified by:
      populateAdornedEntityFormFields in interface FormBuilderService
    • populateMapEntityFormFields

      public void populateMapEntityFormFields(EntityForm ef, Entity entity)
      Description copied from interface: FormBuilderService
      Sets values for the necessary map fields on the EntityForm from the specified entity.
      Specified by:
      populateMapEntityFormFields in interface FormBuilderService
    • buildAdornedListForm

      public EntityForm buildAdornedListForm(AdornedTargetCollectionMetadata adornedMd, AdornedTargetList adornedList, String parentId, boolean isViewCollectionItem, List<SectionCrumb> sectionCrumbs, boolean isAdd) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Builds the EntityForm used in modal dialogs when adding items to adorned target collections.
      Specified by:
      buildAdornedListForm in interface FormBuilderService
      Returns:
      the EntityForm
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • buildAdornedListForm

      public EntityForm buildAdornedListForm(AdornedTargetCollectionMetadata adornedMd, AdornedTargetList adornedList, String parentId, boolean isViewCollectionItem, EntityForm ef, List<SectionCrumb> sectionCrumbs, boolean isAdd) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Equivalent to #buildAdornedListForm(AdornedTargetCollectionMetadata, AdornedTargetList, String) except rather than creating a new EntityForm this simply uses the EntityForm that was passed in as ef. Used mainly when rebuilding an EntityForm after it has already been bound by Spring.

      Before invoking this method, you should invoke EntityForm.clearFieldsMap() to ensure that you have a clean set of field groups and tabs for this method to work with

      Specified by:
      buildAdornedListForm in interface FormBuilderService
      ef - the form DTO to populate
      Returns:
      the original EntityForm passed in but fully populated
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • buildMapForm

      public EntityForm buildMapForm(MapMetadata mapMd, MapStructure mapStructure, ClassMetadata cmd, String parentId) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Builds the EntityForm used in modal dialogs when adding items to map collections.
      Specified by:
      buildMapForm in interface FormBuilderService
      Returns:
      the EntityForm
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • buildMapForm

      public EntityForm buildMapForm(MapMetadata mapMd, MapStructure mapStructure, ClassMetadata cmd, String parentId, EntityForm ef) throws org.broadleafcommerce.common.exception.ServiceException
      Description copied from interface: FormBuilderService
      Equivalent to FormBuilderService.buildMapForm(MapMetadata, MapStructure, ClassMetadata, String) except rather than creating a new EntityForm this simply uses the EntityForm that was passed in as ef. Used mainly when rebuilding an EntityForm after it has already been bound by Spring.

      Before invoking this method, you should invoke EntityForm.clearFieldsMap() to ensure that you have a clean set of field groups and tabs for this method to work with

      Specified by:
      buildMapForm in interface FormBuilderService
      ef - the form DTO to populate
      Returns:
      the original EntityForm passed in but fully populated
      Throws:
      org.broadleafcommerce.common.exception.ServiceException
    • getValueClassNames

      protected List<String> getValueClassNames(String valueClassName)
    • filterMapFormProperties

      protected void filterMapFormProperties(List<Property> mapFormProperties, List<String> classNames)
    • createStandardEntityForm

      protected EntityForm createStandardEntityForm()
    • createStandardAdornedEntityForm

      protected EntityForm createStandardAdornedEntityForm()
    • getGridHiddenVisibilities

      protected org.broadleafcommerce.common.presentation.client.VisibilityEnum[] getGridHiddenVisibilities()
    • getFormHiddenVisibilities

      protected org.broadleafcommerce.common.presentation.client.VisibilityEnum[] getFormHiddenVisibilities()