private static ParseRepresentationAttrResult GetEmptyToken(SchemaAttributeResponse attr)
        {
            RepresentationAttribute result = null;

            switch (attr.Type)
            {
            case Common.Constants.SchemaAttributeTypes.String:
            case Common.Constants.SchemaAttributeTypes.Reference:
                result = GetEmptyToken(attr, string.Empty);
                break;

            case Common.Constants.SchemaAttributeTypes.Boolean:
                result = GetEmptyToken(attr, default(bool));
                break;

            case Common.Constants.SchemaAttributeTypes.Decimal:
                result = GetEmptyToken(attr, default(decimal));
                break;

            case Common.Constants.SchemaAttributeTypes.DateTime:
                result = GetEmptyToken(attr, default(DateTime));
                break;

            case Common.Constants.SchemaAttributeTypes.Integer:
                result = GetEmptyToken(attr, default(int));
                break;

            case Common.Constants.SchemaAttributeTypes.Complex:
                result = new ComplexRepresentationAttribute(attr);
                break;

            default:
                return(new ParseRepresentationAttrResult
                {
                    IsParsed = false,
                    ErrorMessage = string.Format(ErrorMessages.TheAttributeTypeIsNotSupported, attr.Type)
                });
            }

            return(new ParseRepresentationAttrResult
            {
                IsParsed = true,
                RepresentationAttribute = result
            });
        }
        private static bool Equals(RepresentationAttribute attr, ComparisonOperators op, bool value)
        {
            if (attr.SchemaAttribute.MultiValued)
            {
                var enumAttr = attr as SingularRepresentationAttribute <IEnumerable <bool> >;
                if (enumAttr == null)
                {
                    return(false);
                }

                switch (op)
                {
                case ComparisonOperators.co:
                    return(enumAttr.Value.Contains(value));
                }

                return(false);
            }

            var attrValue = attr as SingularRepresentationAttribute <bool>;

            if (attrValue == null)
            {
                return(false);
            }

            switch (op)
            {
            case ComparisonOperators.eq:
                return(attrValue.Value.Equals(value));

            case ComparisonOperators.ne:
                return(!attrValue.Value.Equals(value));

            case ComparisonOperators.pr:
                return(true);
            }

            return(false);
        }
Пример #3
0
        public Model.RepresentationAttribute Transform(RepresentationAttribute attr)
        {
            var record = new Model.RepresentationAttribute
            {
                Id       = Guid.NewGuid().ToString(),
                Children = new List <Model.RepresentationAttribute>()
            };

            if (attr.SchemaAttribute != null)
            {
                record.SchemaAttributeId = attr.SchemaAttribute.Id;
            }

            var complexAttr = attr as ComplexRepresentationAttribute;

            if (complexAttr != null)
            {
                if (complexAttr.Values != null)
                {
                    foreach (var child in complexAttr.Values)
                    {
                        var transformed = Transform(child);
                        if (transformed == null)
                        {
                            continue;
                        }

                        transformed.Parent = record;
                        record.Children.Add(transformed);
                    }
                }
                return(record);
            }

            record.Value = attr.GetSerializedValue();
            return(record);
        }
        private bool Set(RepresentationAttribute attr, RepresentationAttribute attrToBeSet)
        {
            switch (attr.SchemaAttribute.Type)
            {
            case Common.Constants.SchemaAttributeTypes.String:
                var strAttr        = attr as SingularRepresentationAttribute <string>;
                var strAttrToBeSet = attrToBeSet as SingularRepresentationAttribute <string>;
                if (strAttr == null || strAttrToBeSet == null)
                {
                    return(false);
                }

                strAttr.Value = strAttrToBeSet.Value;
                break;

            case Common.Constants.SchemaAttributeTypes.Boolean:
                var bAttr        = attr as SingularRepresentationAttribute <bool>;
                var bAttrToBeSet = attrToBeSet as SingularRepresentationAttribute <bool>;
                if (bAttr == null || bAttrToBeSet == null)
                {
                    return(false);
                }

                bAttr.Value = bAttrToBeSet.Value;
                break;

            case Common.Constants.SchemaAttributeTypes.DateTime:
                var dAttr        = attr as SingularRepresentationAttribute <DateTime>;
                var dAttrToBeSet = attrToBeSet as SingularRepresentationAttribute <DateTime>;
                if (dAttr == null || dAttrToBeSet == null)
                {
                    return(false);
                }

                dAttr.Value = dAttrToBeSet.Value;
                break;

            case Common.Constants.SchemaAttributeTypes.Integer:
                var iAttr        = attr as SingularRepresentationAttribute <int>;
                var iAttrToBeSet = attrToBeSet as SingularRepresentationAttribute <int>;
                if (iAttr == null || iAttrToBeSet == null)
                {
                    return(false);
                }

                iAttr.Value = iAttrToBeSet.Value;
                break;

            case Common.Constants.SchemaAttributeTypes.Decimal:
                var deAttr        = attr as SingularRepresentationAttribute <decimal>;
                var deAttrToBeSet = attrToBeSet as SingularRepresentationAttribute <decimal>;
                if (deAttr == null || deAttrToBeSet == null)
                {
                    return(false);
                }

                deAttr.Value = deAttrToBeSet.Value;
                break;

            case Common.Constants.SchemaAttributeTypes.Complex:
                var cAttr       = attr as ComplexRepresentationAttribute;
                var cAttrToBSet = attrToBeSet as ComplexRepresentationAttribute;
                if (cAttr == null || cAttrToBSet == null)
                {
                    return(false);
                }

                cAttr.Values = cAttrToBSet.Values;
                break;

            default:
                return(false);
            }

            return(true);
        }
        private bool Remove(RepresentationAttribute attr, RepresentationAttribute attrToBeRemoved)
        {
            switch (attr.SchemaAttribute.Type)
            {
            case Common.Constants.SchemaAttributeTypes.String:
                var strAttr            = attr as SingularRepresentationAttribute <IEnumerable <string> >;
                var strAttrToBeRemoved = attrToBeRemoved as SingularRepresentationAttribute <IEnumerable <string> >;
                if (strAttr == null || strAttrToBeRemoved == null)
                {
                    return(false);
                }

                strAttr.Value = strAttr.Value.Except(strAttrToBeRemoved.Value);
                break;

            case Common.Constants.SchemaAttributeTypes.Boolean:
                var bAttr            = attr as SingularRepresentationAttribute <IEnumerable <bool> >;
                var bAttrToBeRemoved = attrToBeRemoved as SingularRepresentationAttribute <IEnumerable <bool> >;
                if (bAttr == null || bAttrToBeRemoved == null)
                {
                    return(false);
                }

                bAttr.Value = bAttr.Value.Except(bAttrToBeRemoved.Value);
                break;

            case Common.Constants.SchemaAttributeTypes.DateTime:
                var dAttr            = attr as SingularRepresentationAttribute <IEnumerable <DateTime> >;
                var dAttrToBeRemoved = attrToBeRemoved as SingularRepresentationAttribute <IEnumerable <DateTime> >;
                if (dAttr == null || dAttrToBeRemoved == null)
                {
                    return(false);
                }

                dAttr.Value = dAttr.Value.Except(dAttrToBeRemoved.Value);
                break;

            case Common.Constants.SchemaAttributeTypes.Complex:
                var cAttr            = attr as ComplexRepresentationAttribute;
                var cAttrToBeRemoved = attrToBeRemoved as ComplexRepresentationAttribute;
                if (cAttr == null || cAttrToBeRemoved == null)
                {
                    return(false);
                }

                var attrsToBeRemoved = new List <RepresentationAttribute>();
                foreach (var attrToBeRemovedValue in cAttrToBeRemoved.Values)
                {
                    var removed = cAttr.Values.FirstOrDefault(c => attrToBeRemovedValue.Equals(c));
                    if (removed == null)
                    {
                        continue;
                    }

                    attrsToBeRemoved.Add(removed);
                }

                cAttr.Values = cAttr.Values.Where(v => !attrsToBeRemoved.Contains(v));
                break;

            default:
                return(false);
            }

            return(true);
        }
Пример #6
0
        public Model.RepresentationAttribute Transform(RepresentationAttribute attr)
        {
            var record = new Model.RepresentationAttribute
            {
                Id       = Guid.NewGuid().ToString(),
                Children = new List <Model.RepresentationAttribute>()
            };

            if (attr.SchemaAttribute != null)
            {
                record.SchemaAttributeId = attr.SchemaAttribute.Id;
            }

            var complexAttr = attr as ComplexRepresentationAttribute;

            if (complexAttr != null)
            {
                if (complexAttr.Values != null)
                {
                    foreach (var child in complexAttr.Values)
                    {
                        var transformed = Transform(child);
                        if (transformed == null)
                        {
                            continue;
                        }

                        transformed.Parent = record;
                        record.Children.Add(transformed);
                    }
                }
                return(record);
            }


            if (attr.SchemaAttribute.MultiValued)
            {
                var singular = attr as SingularRepresentationAttribute <IEnumerable <string> >;
                if (singular != null)
                {
                    var representationAttributeValues = new List <Model.RepresentationAttributeValue>();
                    switch (attr.SchemaAttribute.Type)
                    {
                    case Common.Constants.SchemaAttributeTypes.Boolean:
                    case Common.Constants.SchemaAttributeTypes.String:
                    case Common.Constants.SchemaAttributeTypes.Integer:
                    case Common.Constants.SchemaAttributeTypes.Decimal:
                        foreach (var value in singular.Value)
                        {
                            representationAttributeValues.Add(new Model.RepresentationAttributeValue
                            {
                                Id    = Guid.NewGuid().ToString(),
                                Value = value.ToString()
                            });
                        }
                        break;

                    case Common.Constants.SchemaAttributeTypes.DateTime:
                        foreach (var value in singular.Value)
                        {
                            DateTime dt;
                            if (DateTime.TryParse(value, out dt))
                            {
                                representationAttributeValues.Add(new Model.RepresentationAttributeValue
                                {
                                    Id    = Guid.NewGuid().ToString(),
                                    Value = dt.ToUnix().ToString()
                                });
                            }
                        }
                        break;
                    }

                    record.Values = representationAttributeValues;
                }
            }
            else
            {
                var value = attr.GetValue();
                switch (attr.SchemaAttribute.Type)
                {
                case Common.Constants.SchemaAttributeTypes.Boolean:
                case Common.Constants.SchemaAttributeTypes.String:
                    record.Value = value == null ? string.Empty : value.ToString();
                    break;

                case Common.Constants.SchemaAttributeTypes.Decimal:
                    var dec = (decimal)value;
                    record.ValueNumber = (double)dec;
                    break;

                case Common.Constants.SchemaAttributeTypes.Integer:
                    var i = (int)value;
                    record.ValueNumber = i;
                    break;

                case Common.Constants.SchemaAttributeTypes.DateTime:
                    var d = (DateTime)value;
                    record.ValueNumber = d.ToUnix();
                    break;
                }
            }

            return(record);
        }
 private static bool Equals(RepresentationAttribute source, RepresentationAttribute target)
 {
     return(source.CompareTo(target) == 0);
 }
 private static bool AssignValues(RepresentationAttribute source, RepresentationAttribute target)
 {
     return(source.SetValue(target));
 }
        private async Task <UpdateResponse> UpdateAttribute(RepresentationAttribute source, RepresentationAttribute target, string resourceType)
        {
            var result        = new UpdateResponse();
            var complexSource = source as ComplexRepresentationAttribute;
            var complexTarget = target as ComplexRepresentationAttribute;

            if (complexTarget != null)
            {
                var schemaAttribute = complexTarget.SchemaAttribute;
                if (schemaAttribute.MultiValued)
                {
                    // Check mutability
                    if (schemaAttribute.Mutability == Common.Constants.SchemaAttributeMutability.Immutable)
                    {
                        if (complexTarget.CompareTo(complexSource) != 0)
                        {
                            result.SetError(_errorResponseFactory.CreateError(string.Format(ErrorMessages.TheImmutableAttributeCannotBeUpdated, schemaAttribute.Name),
                                                                              HttpStatusCode.BadRequest,
                                                                              Common.Constants.ScimTypeValues.Mutability));
                            return(result);
                        }
                    }

                    // Check uniqueness
                    if (schemaAttribute.Uniqueness == Common.Constants.SchemaAttributeUniqueness.Server)
                    {
                        var filter      = _filterParser.Parse(complexTarget.FullPath);
                        var uniqueAttrs = await _representationStore.SearchValues(resourceType, filter);

                        if (uniqueAttrs.Any())
                        {
                            if (uniqueAttrs.Any(a => a.CompareTo(complexTarget) == 0))
                            {
                                result.SetError(_errorResponseFactory.CreateError(
                                                    string.Format(ErrorMessages.TheAttributeMustBeUnique, complexTarget.SchemaAttribute.Name),
                                                    HttpStatusCode.BadRequest,
                                                    Common.Constants.ScimTypeValues.Uniqueness));
                                return(result);
                            }
                        }
                    }
                }

                complexSource.Values = complexTarget.Values;
                return(result);
            }

            // Check mutability
            if (target.SchemaAttribute.Mutability == Common.Constants.SchemaAttributeMutability.Immutable)
            {
                if (source.CompareTo(target) != 0)
                {
                    result.SetError(_errorResponseFactory.CreateError(string.Format(ErrorMessages.TheImmutableAttributeCannotBeUpdated, target.SchemaAttribute.Name),
                                                                      HttpStatusCode.BadRequest,
                                                                      Common.Constants.ScimTypeValues.Mutability));
                    return(result);
                }
            }

            // Check uniqueness
            if (target.SchemaAttribute.Uniqueness == Common.Constants.SchemaAttributeUniqueness.Server)
            {
                var filter      = _filterParser.Parse(target.FullPath);
                var uniqueAttrs = await _representationStore.SearchValues(resourceType, filter);

                if (uniqueAttrs.Any())
                {
                    if (uniqueAttrs.Any(a => a.CompareTo(target) == 0))
                    {
                        result.SetError(_errorResponseFactory.CreateError(
                                            string.Format(ErrorMessages.TheAttributeMustBeUnique, target.SchemaAttribute.Name),
                                            HttpStatusCode.BadRequest,
                                            Common.Constants.ScimTypeValues.Uniqueness));
                        return(result);
                    }
                }
            }

            // Assign the values
            AssignValues(source, target);
            return(result);
        }
        /// <summary>
        /// Parse json and returns the representation.
        /// </summary>
        /// <exception cref="ArgumentNullException">Thrown when one of the parameter is null.</exception>
        /// <param name="jObj">JSON</param>
        /// <param name="attribute">Schema attribute</param>
        /// <param name="checkStrategy">Strategy used to check the parameters.</param>
        /// <returns>Representation or null.</returns>
        public ParseRepresentationAttrResult GetRepresentation(JToken jObj, SchemaAttributeResponse attribute, CheckStrategies checkStrategy)
        {
            if (jObj == null)
            {
                throw new ArgumentNullException(nameof(jObj));
            }

            if (attribute == null)
            {
                throw new ArgumentNullException(nameof(attribute));
            }

            Action <ComplexSchemaAttributeResponse, List <RepresentationAttribute>, JToken, RepresentationAttribute> setRepresentationCallback = (attr, lst, tok, reprAttr) =>
            {
                foreach (var subAttribute in attr.SubAttributes)
                {
                    var rep = GetRepresentation(tok, subAttribute, checkStrategy);
                    if (rep.IsParsed)
                    {
                        rep.RepresentationAttribute.Parent = reprAttr;
                        lst.Add(rep.RepresentationAttribute);
                    }
                }
            };
            var token = jObj.SelectToken(attribute.Name);

            // 1. Check the attribute is required
            if (token == null)
            {
                if (attribute.Required && checkStrategy == CheckStrategies.Strong)
                {
                    return(new ParseRepresentationAttrResult
                    {
                        IsParsed = false,
                        ErrorMessage = string.Format(ErrorMessages.TheAttributeIsRequired, attribute.Name)
                    });
                }

                // Add empty attribute.
                return(GetEmptyToken(attribute));
            }

            // 2. Check is an array
            JArray jArr = null;

            if (attribute.MultiValued)
            {
                jArr = token as JArray;
                if (jArr == null)
                {
                    return(new ParseRepresentationAttrResult
                    {
                        IsParsed = false,
                        ErrorMessage = string.Format(ErrorMessages.TheAttributeIsNotAnArray, attribute.Name)
                    });
                }
            }

            // 3. Create complex attribute
            var complexAttribute = attribute as ComplexSchemaAttributeResponse;

            if (complexAttribute != null)
            {
                var representation = new ComplexRepresentationAttribute(complexAttribute);
                var values         = new List <RepresentationAttribute>();
                if (complexAttribute.MultiValued)
                {
                    // 3.1 Contains an array
                    if (jArr.Count > 0)
                    {
                        foreach (var subToken in token)
                        {
                            var subRepresentation = new ComplexRepresentationAttribute(null);
                            var subValues         = new List <RepresentationAttribute>();
                            setRepresentationCallback(complexAttribute, subValues, subToken, subRepresentation);
                            subRepresentation.Values = subValues;
                            values.Add(subRepresentation);
                            subRepresentation.Parent = representation;
                        }
                    }
                    else
                    {
                        values.Add(new ComplexRepresentationAttribute(null)
                        {
                            Values = new List <RepresentationAttribute>()
                        });
                    }
                }
                else
                {
                    // 3.2 Doesn't contain array
                    setRepresentationCallback(complexAttribute, values, token, representation);
                }

                representation.Values = values;
                return(new ParseRepresentationAttrResult
                {
                    IsParsed = true,
                    RepresentationAttribute = representation
                });
            }

            RepresentationAttribute result = null;

            // 4. Create singular attribute.
            // Note : Don't cast to object to avoid unecessaries boxing operations ...
            switch (attribute.Type)
            {
            case Common.Constants.SchemaAttributeTypes.String:
                result = GetSingularToken <string>(jArr, attribute, token);
                break;

            case Common.Constants.SchemaAttributeTypes.Boolean:
                result = GetSingularToken <bool>(jArr, attribute, token);
                break;

            case Common.Constants.SchemaAttributeTypes.Decimal:
                result = GetSingularToken <decimal>(jArr, attribute, token);
                break;

            case Common.Constants.SchemaAttributeTypes.DateTime:
                result = GetSingularToken <DateTime>(jArr, attribute, token);
                break;

            case Common.Constants.SchemaAttributeTypes.Integer:
                result = GetSingularToken <int>(jArr, attribute, token);
                break;

            default:
                return(new ParseRepresentationAttrResult
                {
                    IsParsed = false,
                    ErrorMessage = string.Format(ErrorMessages.TheAttributeTypeIsNotSupported, attribute.Type)
                });
            }

            if (result == null)
            {
                return(new ParseRepresentationAttrResult
                {
                    IsParsed = false,
                    ErrorMessage = string.Format(ErrorMessages.TheAttributeTypeIsNotCorrect, attribute.Name, attribute.Type)
                });
            }

            return(new ParseRepresentationAttrResult
            {
                RepresentationAttribute = result,
                IsParsed = true
            });
        }
        private bool UpdateAttribute(RepresentationAttribute source, RepresentationAttribute target, IEnumerable <Representation> allRepresentations, out ErrorResponse error)
        {
            error = null;
            var complexSource = source as ComplexRepresentationAttribute;
            var complexTarget = target as ComplexRepresentationAttribute;

            if (complexTarget != null)
            {
                var schemaAttribute = complexTarget.SchemaAttribute;
                if (schemaAttribute.MultiValued)
                {
                    // Check mutability
                    if (schemaAttribute.Mutability == Common.Constants.SchemaAttributeMutability.Immutable)
                    {
                        if (complexTarget.CompareTo(complexSource) != 0)
                        {
                            error = _errorResponseFactory.CreateError(string.Format(ErrorMessages.TheImmutableAttributeCannotBeUpdated, schemaAttribute.Name),
                                                                      HttpStatusCode.BadRequest,
                                                                      Common.Constants.ScimTypeValues.Mutability);
                            return(false);
                        }
                    }

                    // Check uniqueness
                    if (schemaAttribute.Uniqueness == Common.Constants.SchemaAttributeUniqueness.Server && allRepresentations != null && allRepresentations.Any())
                    {
                        var filter      = _filterParser.Parse(complexTarget.FullPath);
                        var uniqueAttrs = new List <RepresentationAttribute>();
                        foreach (var records in allRepresentations.Select(r => filter.Evaluate(r)))
                        {
                            uniqueAttrs.AddRange(records);
                        }

                        if (uniqueAttrs.Any())
                        {
                            if (uniqueAttrs.Any(a => a.CompareTo(complexTarget) == 0))
                            {
                                error = _errorResponseFactory.CreateError(
                                    string.Format(ErrorMessages.TheAttributeMustBeUnique, complexTarget.SchemaAttribute.Name),
                                    HttpStatusCode.BadRequest,
                                    Common.Constants.ScimTypeValues.Uniqueness);
                                return(false);
                            }
                        }
                    }
                }

                complexSource.Values = complexTarget.Values;
                return(true);
            }

            // Check mutability
            if (target.SchemaAttribute.Mutability == Common.Constants.SchemaAttributeMutability.Immutable)
            {
                if (source.CompareTo(target) != 0)
                {
                    error = _errorResponseFactory.CreateError(string.Format(ErrorMessages.TheImmutableAttributeCannotBeUpdated, target.SchemaAttribute.Name),
                                                              HttpStatusCode.BadRequest,
                                                              Common.Constants.ScimTypeValues.Mutability);
                    return(false);
                }
            }

            // Check uniqueness
            if (target.SchemaAttribute.Uniqueness == Common.Constants.SchemaAttributeUniqueness.Server && allRepresentations != null && allRepresentations.Any())
            {
                var filter      = _filterParser.Parse(target.FullPath);
                var uniqueAttrs = new List <RepresentationAttribute>();
                foreach (var records in allRepresentations.Select(r => filter.Evaluate(r)))
                {
                    uniqueAttrs.AddRange(records);
                }

                if (uniqueAttrs.Any())
                {
                    if (uniqueAttrs.Any(a => a.CompareTo(target) == 0))
                    {
                        error = _errorResponseFactory.CreateError(
                            string.Format(ErrorMessages.TheAttributeMustBeUnique, target.SchemaAttribute.Name),
                            HttpStatusCode.BadRequest,
                            Common.Constants.ScimTypeValues.Uniqueness);
                        return(false);
                    }
                }
            }

            // Assign the values
            return(AssignValues(source, target));
        }
Пример #12
0
        private static JToken GetSingularToken <T>(SchemaAttributeResponse attribute, RepresentationAttribute attr, bool isArray)
        {
            if (isArray)
            {
                var enumSingularRepresentation = attr as SingularRepresentationAttribute <IEnumerable <T> >;
                if (enumSingularRepresentation == null)
                {
                    throw new InvalidOperationException(string.Format(ErrorMessages.TheAttributeTypeIsNotCorrect, attribute.Name, attribute.Type));
                }

                return(new JProperty(enumSingularRepresentation.SchemaAttribute.Name, enumSingularRepresentation.Value));
            }
            else
            {
                var singularRepresentation = attr as SingularRepresentationAttribute <T>;
                if (singularRepresentation == null)
                {
                    throw new InvalidOperationException(string.Format(ErrorMessages.TheAttributeTypeIsNotCorrect, attribute.Name, attribute.Type));
                }

                return(new JProperty(singularRepresentation.SchemaAttribute.Name, singularRepresentation.Value));
            }
        }
Пример #13
0
        private static JToken GetToken(RepresentationAttribute attr, SchemaAttributeResponse attribute)
        {
            // 1. Check the attribute is required
            if (attr == null)
            {
                if (attribute.Required)
                {
                    throw new InvalidOperationException(string.Format(ErrorMessages.TheAttributeIsRequired, attribute.Name));
                }

                return(null);
            }

            // 2. Create complex attribute
            var complexAttribute = attribute as ComplexSchemaAttributeResponse;

            if (complexAttribute != null)
            {
                var complexRepresentation = attr as ComplexRepresentationAttribute;
                if (complexRepresentation == null)
                {
                    throw new InvalidOperationException(string.Format(ErrorMessages.TheAttributeIsNotComplex, attribute.Name));
                }

                // 2.1 Complex attribute[Complex attribute]
                if (attribute.MultiValued)
                {
                    var array = new JArray();
                    if (complexRepresentation.Values != null)
                    {
                        foreach (var subRepresentation in complexRepresentation.Values)
                        {
                            var subComplex = subRepresentation as ComplexRepresentationAttribute;
                            if (subComplex == null)
                            {
                                throw new InvalidOperationException(ErrorMessages.TheComplexAttributeArrayShouldContainsOnlyComplexAttribute);
                            }

                            var obj = new JObject();
                            foreach (var subAttr in subComplex.Values)
                            {
                                var att = complexAttribute.SubAttributes.FirstOrDefault(a => a.Name == subAttr.SchemaAttribute.Name);
                                if (att == null)
                                {
                                    continue;
                                }

                                obj.Add(GetToken(subAttr, att));
                            }

                            array.Add(obj);
                        }
                    }

                    return(new JProperty(complexRepresentation.SchemaAttribute.Name, array));
                }

                var properties = new List <JToken>();
                // 2.2 Complex attribute
                if (complexRepresentation.Values != null)
                {
                    foreach (var subRepresentation in complexRepresentation.Values)
                    {
                        var subAttribute = complexAttribute.SubAttributes.FirstOrDefault(a => a.Name == subRepresentation.SchemaAttribute.Name);
                        if (subAttribute == null)
                        {
                            continue;
                        }

                        properties.Add(GetToken(subRepresentation, subAttribute));
                    }
                }

                var props = new JObject(properties);
                return(new JProperty(complexRepresentation.SchemaAttribute.Name, props));
            }

            // 3. Create singular attribute
            switch (attribute.Type)
            {
            case Common.Constants.SchemaAttributeTypes.String:
            case Common.Constants.SchemaAttributeTypes.Reference:
                return(GetSingularToken <string>(attribute, attr, attribute.MultiValued));

            case Common.Constants.SchemaAttributeTypes.Boolean:
                return(GetSingularToken <bool>(attribute, attr, attribute.MultiValued));

            case Common.Constants.SchemaAttributeTypes.Decimal:
                return(GetSingularToken <decimal>(attribute, attr, attribute.MultiValued));

            case Common.Constants.SchemaAttributeTypes.DateTime:
                return(GetSingularToken <DateTime>(attribute, attr, attribute.MultiValued));

            case Common.Constants.SchemaAttributeTypes.Integer:
                return(GetSingularToken <int>(attribute, attr, attribute.MultiValued));

            default:
                throw new InvalidOperationException(string.Format(ErrorMessages.TheAttributeTypeIsNotSupported, attribute.Type));
            }
        }