@Override
 public void constraintOnlyLeafTypeDefinition(String repositoryId, String objectTypeId) {
   TypeDefinitionContainer tdc = typeManager.getTypeById(repositoryId, objectTypeId);
   if (!CollectionUtils.isEmpty(tdc.getChildren())) {
     String msg =
         "Cannot delete a type definition which has sub types"
             + " [objectTypeId = "
             + objectTypeId
             + "]";
     throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409);
   }
 }
  @Override
  public <T> void constraintPropertyValue(
      String repositoryId, TypeDefinition typeDefinition, Properties properties, String objectId) {
    Map<String, PropertyDefinition<?>> propertyDefinitions =
        typeDefinition.getPropertyDefinitions();

    // Adding secondary types and its properties MAY be done in the same
    // operation
    List<String> secIds =
        DataUtil.getIdListProperty(properties, PropertyIds.SECONDARY_OBJECT_TYPE_IDS);
    if (CollectionUtils.isNotEmpty(secIds)) {
      for (String secId : secIds) {
        TypeDefinition sec = typeManager.getTypeById(repositoryId, secId).getTypeDefinition();
        for (Entry<String, PropertyDefinition<?>> entry : sec.getPropertyDefinitions().entrySet()) {
          if (!propertyDefinitions.containsKey(entry.getKey())) {
            propertyDefinitions.put(entry.getKey(), entry.getValue());
          }
        }
      }
    }

    for (PropertyData<?> _pd : properties.getPropertyList()) {
      PropertyData<T> pd = (PropertyData<T>) _pd;
      PropertyDefinition<T> propertyDefinition =
          (PropertyDefinition<T>) propertyDefinitions.get(pd.getId());
      // If an input property is not defined one, output error.
      if (propertyDefinition == null) constraint(objectId, "An undefined property is provided!");

      // Check "required" flag
      if (propertyDefinition.isRequired() && !DataUtil.valueExist(pd.getValues()))
        constraint(objectId, "An required property is not provided!");

      // Check choices
      constraintChoices(propertyDefinition, pd, objectId);

      // Check min/max length
      switch (propertyDefinition.getPropertyType()) {
        case STRING:
          constraintStringPropertyValue(propertyDefinition, pd, objectId);
          break;
        case DECIMAL:
          constraintDecimalPropertyValue(propertyDefinition, pd, objectId);
        case INTEGER:
          constraintIntegerPropertyValue(propertyDefinition, pd, objectId);
          break;
        default:
          break;
      }
    }
  }
  @Override
  public void invalidArgumentCreatableType(String repositoryId, TypeDefinition type) {
    String msg = "";

    String parentId = type.getParentTypeId();
    if (typeManager.getTypeById(repositoryId, parentId) == null) {
      msg = "Specified parent type does not exist";
    } else {
      TypeDefinition parent = typeManager.getTypeById(repositoryId, parentId).getTypeDefinition();
      if (parent.getTypeMutability() == null) {
        msg = "Specified parent type does not have TypeMutability";
      } else {
        boolean canCreate = (parent.getTypeMutability() == null) ? false : true;
        if (!canCreate) {
          msg = "Specified parent type has TypeMutability.canCreate = false";
        }
      }
    }

    if (!StringUtils.isEmpty(msg)) {
      msg = msg + " [objectTypeId = " + type.getId() + "]";
      invalidArgument(msg);
    }
  }
  @Override
  public void invalidArgumentSecondaryTypeIds(String repositoryId, Properties properties) {
    if (properties == null) return;
    Map<String, PropertyData<?>> map = properties.getProperties();
    if (MapUtils.isEmpty(map)) return;

    List<String> results = new ArrayList<String>();
    PropertyData<?> ids = map.get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS);
    if (ids == null || CollectionUtils.isEmpty(ids.getValues())) return;
    for (Object _id : ids.getValues()) {
      String id = (String) _id;
      TypeDefinitionContainer tdc = typeManager.getTypeById(repositoryId, id);
      if (tdc == null) {
        results.add(id);
      }
    }

    if (CollectionUtils.isNotEmpty(results)) {
      String msg =
          "Invalid cmis:SecondaryObjectTypeIds are provided:" + StringUtils.join(results, ",");
      invalidArgument(msg);
    }
  }