/** {@inheritDoc} */
  public List<Map<String, String>> getExportGroups(final String language) {

    final List<DataGroup> dataGroups = dataDescriptorResolver.getGroups();

    final Set<Map<String, String>> out =
        new TreeSet<Map<String, String>>(
            new Comparator<Map<String, String>>() {
              @Override
              public int compare(final Map<String, String> o1, final Map<String, String> o2) {
                int comp = o1.get("label").compareToIgnoreCase(o2.get("label"));
                if (comp == 0) {
                  comp = o1.get("name").compareToIgnoreCase(o2.get("name"));
                }
                return comp;
              }
            });
    for (final DataGroup dataGroup : dataGroups) {
      if (StringUtils.isBlank(dataGroup.getQualifier())
          || federationFacade.isManageable(dataGroup.getQualifier(), ShopDTO.class)) {
        final Map<String, String> grp = new HashMap<String, String>();
        grp.put("name", dataGroup.getName());
        final I18NModel model =
            new FailoverStringI18NModel(dataGroup.getDisplayName(), dataGroup.getName());
        grp.put("label", model.getValue(language));
        out.add(grp);
      }
    }

    return new ArrayList<Map<String, String>>(out);
  }
 /** {@inheritDoc} */
 public void remove(final long id) throws Exception {
   if (federationFacade.isCurrentUserSystemAdmin()) {
     dtoProductTypeService.remove(id);
   } else {
     throw new AccessDeniedException("Access is denied");
   }
 }
  /** {@inheritDoc} */
  public VoProductType update(final VoProductType vo) throws Exception {
    final ProductTypeDTO typeDTO = dtoProductTypeService.getById(vo.getProducttypeId());
    if (typeDTO != null && federationFacade.isCurrentUserSystemAdmin()) {
      dtoProductTypeService.update(
          voAssemblySupport.assembleDto(ProductTypeDTO.class, VoProductType.class, typeDTO, vo));

      final List<ProdTypeAttributeViewGroupDTO> groups =
          dtoProdTypeAttributeViewGroupService.getByProductTypeId(vo.getProducttypeId());
      final Map<Long, ProdTypeAttributeViewGroupDTO> existing = new HashMap<>();
      for (final ProdTypeAttributeViewGroupDTO group : groups) {
        existing.put(group.getProdTypeAttributeViewGroupId(), group);
      }

      if (vo.getViewGroups() != null) {
        for (final VoProductTypeViewGroup voGroup : vo.getViewGroups()) {
          final ProdTypeAttributeViewGroupDTO dtoToUpdate =
              existing.get(voGroup.getProdTypeAttributeViewGroupId());
          if (dtoToUpdate != null) {
            // update mode
            existing.remove(dtoToUpdate.getProdTypeAttributeViewGroupId());

            dtoProdTypeAttributeViewGroupService.update(
                voAssemblySupport.assembleDto(
                    ProdTypeAttributeViewGroupDTO.class,
                    VoProductTypeViewGroup.class,
                    dtoToUpdate,
                    voGroup));

          } else {
            // insert mode

            final ProdTypeAttributeViewGroupDTO newGroup =
                dtoProdTypeAttributeViewGroupService.getNew();
            newGroup.setProducttypeId(vo.getProducttypeId());

            dtoProdTypeAttributeViewGroupService.create(
                voAssemblySupport.assembleDto(
                    ProdTypeAttributeViewGroupDTO.class,
                    VoProductTypeViewGroup.class,
                    newGroup,
                    voGroup));
          }
        }
      }

      for (final ProdTypeAttributeViewGroupDTO remove : existing.values()) {
        dtoProdTypeAttributeViewGroupService.remove(remove.getProdTypeAttributeViewGroupId());
      }

    } else {
      throw new AccessDeniedException("Access is denied");
    }
    return getById(vo.getProducttypeId());
  }
 /** {@inheritDoc} */
 public VoProductType create(final VoProductTypeInfo vo) throws Exception {
   if (federationFacade.isCurrentUserSystemAdmin()) {
     ProductTypeDTO typeDTO = dtoProductTypeService.getNew();
     typeDTO =
         dtoProductTypeService.create(
             voAssemblySupport.assembleDto(
                 ProductTypeDTO.class, VoProductTypeInfo.class, typeDTO, vo));
     return getById(typeDTO.getProducttypeId());
   } else {
     throw new AccessDeniedException("Access is denied");
   }
 }
  /** {@inheritDoc} */
  public List<VoProductTypeAttr> update(final List<MutablePair<VoProductTypeAttr, Boolean>> vo)
      throws Exception {

    long typeId = 0L;
    if (federationFacade.isCurrentUserSystemAdmin()) {

      final VoAssemblySupport.VoAssembler<VoProductTypeAttr, ProductTypeAttrDTO> asm =
          voAssemblySupport.with(VoProductTypeAttr.class, ProductTypeAttrDTO.class);

      Map<Long, ProductTypeAttrDTO> existing = Collections.emptyMap();
      for (final MutablePair<VoProductTypeAttr, Boolean> item : vo) {
        if (typeId == 0L) {
          typeId = item.getFirst().getProducttypeId();
          existing = mapAvById((List) dtoProductTypeAttrService.getByProductTypeId(typeId));
        } else if (typeId != item.getFirst().getProducttypeId()) {
          throw new AccessDeniedException("Access is denied");
        }

        if (Boolean.valueOf(item.getSecond())) {
          if (item.getFirst().getProductTypeAttrId() > 0L) {
            // delete mode
            dtoProductTypeAttrService.remove(item.getFirst().getProductTypeAttrId());
          }
        } else if (item.getFirst().getProductTypeAttrId() > 0L) {
          // update mode
          final ProductTypeAttrDTO dto = existing.get(item.getFirst().getProductTypeAttrId());
          if (dto != null) {
            asm.assembleDto(dto, item.getFirst());
            dtoProductTypeAttrService.update(dto);
          } else {
            ShopCodeContext.getLog(this)
                .warn(
                    "Update skipped for inexistent ID {}", item.getFirst().getProductTypeAttrId());
          }
        } else {
          // insert mode
          final ProductTypeAttrDTO dto = dtoProductTypeAttrService.getNew();
          dto.setProducttypeId(typeId);
          dto.setAttributeDTO(
              dtoAttributeService.getById(item.getFirst().getAttribute().getAttributeId()));
          asm.assembleDto(dto, item.getFirst());
          this.dtoProductTypeAttrService.create(dto);
        }
      }

    } else {
      throw new AccessDeniedException("Access is denied");
    }

    return getTypeAttributes(typeId);
  }
 /**
  * Verify access of the current user.
  *
  * @param object target object to update
  * @throws AccessDeniedException
  */
 protected void validateAccessAfterUpdate(final Object object, final Class objectType)
     throws AccessDeniedException {
   if (!federationFacade.isManageable(object, objectType)) {
     throw new AccessDeniedException("access denied");
   }
 }