public ODataAvroParameterWriter(ODataAvroOutputContext outputContext, IEdmOperation operation)
        {
            Debug.Assert(outputContext != null, "outputContext != null");
            Debug.Assert(operation != null, "operation != null");

            this.outputContext = outputContext;
            schema = (RecordSchema)this.outputContext.AvroWriter.UpdateSchema(null, this.GetTmpType(operation));
            this.record = new AvroRecord(schema);
        }
예제 #2
0
        static ODataAvroSchemaGen()
        {
            ErrorSchema = Schema.CreateRecord(AvroConstants.ODataErrorType, null);
            var fields = new[]
                {
                    Schema.CreateField(AvroConstants.ODataErrorFieldErrorCode, Schema.CreateString()),
                    Schema.CreateField(AvroConstants.ODataErrorFieldMessage, Schema.CreateString()),
                };

            Schema.SetFields(ErrorSchema, fields);
        }
        private void VisitCore(RecordSchema s)
        {
            if (this.visited.Contains(s))
            {
                return;
            }
            this.visited.Add(s);

            s.Serializer = new ClassSerializer(s);

            foreach (var field in s.Fields)
            {
                this.VisitDynamic(field);
            }
        }
예제 #4
0
        /// <summary>
        /// Generates the record type schema.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="schemas">The schemas.</param>
        /// <param name="currentDepth">The current depth.</param>
        /// <returns>
        /// Instance of schema.
        /// </returns>
        private TypeSchema BuildRecordTypeSchema(Type type, Dictionary <string, NamedSchema> schemas, uint currentDepth)
        {
            if (type == typeof(DateTimeOffset))
            {
                return(this.settings.UsePosixTime
                    ? (TypeSchema) new LongSchema(type)
                    : new StringSchema(type));
            }

            NamedSchema schema;

            if (schemas.TryGetValue(type.ToString(), out schema))
            {
                return(schema);
            }

            if (type == typeof(Guid))
            {
                var recordName = new SchemaName(type.GetStrippedFullName());
                var attributes = new NamedEntityAttributes(recordName, new List <string>(), string.Empty);
                var result     = new FixedSchema(attributes, 16, type);
                schemas.Add(type.ToString(), result);
                return(result);
            }

            var attr = this.GetNamedEntityAttributesFrom(type);
            AvroContractResolver resolver = this.settings.Resolver;
            var record = new RecordSchema(
                attr,
                type);

            schemas.Add(type.ToString(), record);

            var members = resolver.ResolveMembers(type);

            this.AddRecordFields(members, schemas, currentDepth, record);
            return(record);
        }
        /// <summary>
        /// Sets the fields.
        /// </summary>
        /// <param name="record">
        /// The record.
        /// </param>
        /// <param name="fields">
        /// The fields.
        /// </param>
        public static void SetFields(RecordSchema record, IEnumerable <RecordField> fields)
        {
            if (record == null)
            {
                throw new ArgumentNullException("record");
            }

            if (fields == null)
            {
                throw new ArgumentNullException("fields");
            }

            if (record.Fields.Count != 0)
            {
                throw new InvalidOperationException("Fields can be set only on empty record.");
            }

            int fieldPosition = 0;

            foreach (var field in fields)
            {
                record.AddField(new RecordField(field.NamedEntityAttributes, field.TypeSchema, field.Order, field.HasDefaultValue, field.DefaultValue, field.MemberInfo, fieldPosition++));
            }
        }
        private List <RecordField> BuildReaderFields(RecordSchema w, RecordSchema r, int startPosition)
        {
            var readerFieldsWithDefault = r.Fields.Where(field => field.HasDefaultValue);
            var fieldsToAdd             = new List <RecordField>();

            foreach (var readerField in readerFieldsWithDefault)
            {
                if (!w.Fields.Any(f => this.DoNamesMatch(f, readerField)))
                {
                    var newField = new RecordField(
                        readerField.NamedEntityAttributes,
                        readerField.TypeSchema,
                        readerField.Order,
                        readerField.HasDefaultValue,
                        readerField.DefaultValue,
                        readerField.MemberInfo,
                        startPosition++)
                    {
                        UseDefaultValue = true
                    };

                    fieldsToAdd.Add(newField);
                }
            }

            if (r.RuntimeType == typeof(AvroRecord) &&
                r.Fields.Any(rf => !rf.HasDefaultValue && !w.Fields.Any(wf => this.DoNamesMatch(wf, rf))))
            {
                throw new SerializationException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              "Fields without default values found in type '{0}'. Not corresponding writer fields found.",
                              r.RuntimeType));
            }
            return(fieldsToAdd);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ClassTemplate"/> class.
 /// </summary>
 /// <param name="recordSchema">The record schema.</param>
 /// <param name="userDefinedNamespace">The default namespace.</param>
 /// <param name="forceNamespace">Determines whether the UserDefinedNamespace should be used.</param>
 public ClassTemplate(RecordSchema recordSchema, string userDefinedNamespace, bool forceNamespace)
 {
     this.Schema = recordSchema;
     this.UserDefinedNamespace = userDefinedNamespace;
     this.ForceNamespace = forceNamespace;
 }
        private dynamic CreateDynamicData(RecordSchema recordSchema)
        {
            dynamic expected1 = new AvroRecord(recordSchema);
            dynamic location1 = new AvroRecord(recordSchema.GetField("Location").TypeSchema);
            location1.Floor = 1;
            location1.Room = 243;
            expected1.Location = location1;
            expected1.Value = new byte[] {1, 2, 3, 4, 5};

            return expected1;
        }
예제 #9
0
        /// <summary>
        /// Parses the record type.
        /// </summary>
        /// <param name="record">The record.</param>
        /// <param name="parent">The parent schema.</param>
        /// <param name="namedSchemas">The named schemas.</param>
        /// <returns>
        /// Schema internal representation.
        /// </returns>
        /// <exception cref="System.Runtime.Serialization.SerializationException">Thrown when <paramref name="record"/> can not be parsed properly.</exception>
        private TypeSchema ParseRecordType(JObject record, NamedSchema parent, Dictionary<string, NamedSchema> namedSchemas)
        {
            var name = record.RequiredProperty<string>(Token.Name);
            var nspace = this.GetNamespace(record, parent, name);
            var recordName = new SchemaName(name, nspace);

            var doc = record.OptionalProperty<string>(Token.Doc);
            var aliases = this.GetAliases(record, recordName.Namespace);
            var attributes = new NamedEntityAttributes(recordName, aliases, doc);

            Dictionary<string, string> customAttributes = record.GetAttributesNotIn(StandardProperties.Record);
            var result = new RecordSchema(attributes, typeof(AvroRecord), customAttributes);
            namedSchemas.Add(result.FullName, result);

            List<RecordField> fields = record.OptionalArrayProperty(
                Token.Fields,
                (field, index) =>
                {
                    if (field.Type != JTokenType.Object)
                    {
                        throw new SerializationException(
                            string.Format(CultureInfo.InvariantCulture, "Property 'fields' has invalid value '{0}'.", field));
                    }
                    return this.ParseRecordField(field as JObject, result, namedSchemas, index);
                });

            fields.ForEach(result.AddField);
            return result;
        }
        private void AddRecordFields(
            IEnumerable<MemberSerializationInfo> members,
            Dictionary<string, NamedSchema> schemas,
            uint currentDepth,
            RecordSchema record)
        {
            int index = 0;
            foreach (MemberSerializationInfo info in members)
            {
                var property = info.MemberInfo as PropertyInfo;
                var field = info.MemberInfo as FieldInfo;

                Type memberType;
                if (property != null)
                {
                    memberType = property.PropertyType;
                }
                else if (field != null)
                {
                    memberType = field.FieldType;
                }
                else
                {
                    throw new SerializationException(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "Type member '{0}' is not supported.",
                            info.MemberInfo.MemberType));
                }

                TypeSchema fieldSchema = this.TryBuildUnionSchema(memberType, info.MemberInfo, schemas, currentDepth)
                                         ?? this.TryBuildFixedSchema(memberType, info.MemberInfo, record)
                                         ?? this.CreateSchema(info.Nullable, memberType, schemas, currentDepth + 1);

                var aliases = info
                    .Aliases
                    .Select(alias => alias.Contains(".") ? alias : record.Namespace + "." + alias)
                    .ToList();
                var recordField = new RecordField(
                    new NamedEntityAttributes(new SchemaName(info.Name), aliases, info.Doc),
                    fieldSchema,
                    SortOrder.Ascending,
                    false,
                    null,
                    info.MemberInfo,
                    index++);
                record.AddField(recordField);
            }
        }
        /// <summary>
        /// Generates the record type schema.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="schemas">The schemas.</param>
        /// <param name="currentDepth">The current depth.</param>
        /// <returns>
        /// Instance of schema.
        /// </returns>
        private TypeSchema BuildRecordTypeSchema(Type type, Dictionary<string, NamedSchema> schemas, uint currentDepth)
        {
            if (type == typeof(DateTimeOffset))
            {
                return this.settings.UsePosixTime
                    ? (TypeSchema)new LongSchema(type)
                    : new StringSchema(type);
            }

            NamedSchema schema;
            if (schemas.TryGetValue(type.ToString(), out schema))
            {
                return schema;
            }

            if (type == typeof(Guid))
            {
                var recordName = new SchemaName(type.GetStrippedFullName());
                var attributes = new NamedEntityAttributes(recordName, new List<string>(), string.Empty);
                var result = new FixedSchema(attributes, 16, type);
                schemas.Add(type.ToString(), result);
                return result;
            }

            var attr = this.GetNamedEntityAttributesFrom(type);
            AvroContractResolver resolver = this.settings.Resolver;
            var record = new RecordSchema(
                attr,
                type);
            schemas.Add(type.ToString(), record);

            var members = resolver.ResolveMembers(type);
            this.AddRecordFields(members, schemas, currentDepth, record);
            return record;
        }
예제 #12
0
 private static string GenerateCore(RecordSchema schema, string defaultNamespace, bool forceNamespace)
 {
     return new ClassTemplate(schema, defaultNamespace, forceNamespace).TransformText();
 }
        /// <summary>
        /// Matches if the writer's record contains a field with a name not present in the reader's record, the writer's value for that field is ignored.
        /// </summary>
        /// <param name="w">The writer schema.</param>
        /// <param name="r">The reader schema.</param>
        /// <returns>True if match.</returns>
        private List<RecordField> BuildWriterFields(RecordSchema w, RecordSchema r)
        {
            var fields = new List<RecordField>();
            var writerFields = w.Fields.OrderBy(f => f.FullName);
            foreach (var writerField in writerFields)
            {
                writerField.ShouldBeSkipped = true;

                RecordField readerField = r.Fields.SingleOrDefault(f => this.DoNamesMatch(writerField, f));
                RecordField newField = null;
                if (readerField != null)
                {
                    var schema = this.BuildDynamic(writerField.TypeSchema, readerField.TypeSchema);
                    if (schema == null)
                    {
                        throw new SerializationException(
                            string.Format(
                            CultureInfo.InvariantCulture,
                            "Field '{0}' in type '{1}' does not match the reader field.",
                            writerField.Name,
                            w.RuntimeType));
                    }

                    newField = new RecordField(
                        writerField.NamedEntityAttributes,
                        schema,
                        writerField.Order,
                        writerField.HasDefaultValue,
                        writerField.DefaultValue,
                        readerField.MemberInfo,
                        writerField.Position)
                    {
                        ShouldBeSkipped = false
                    };
                }
                else
                {
                    newField = new RecordField(
                        writerField.NamedEntityAttributes,
                        writerField.TypeSchema,
                        writerField.Order,
                        writerField.HasDefaultValue,
                        writerField.DefaultValue,
                        writerField.MemberInfo,
                        writerField.Position)
                    {
                        ShouldBeSkipped = true
                    };
                }

                fields.Add(newField);
            }
            return fields;
        }
        private List<RecordField> BuildReaderFields(RecordSchema w, RecordSchema r, int startPosition)
        {
            var readerFieldsWithDefault = r.Fields.Where(field => field.HasDefaultValue);
            var fieldsToAdd = new List<RecordField>();
            foreach (var readerField in readerFieldsWithDefault)
            {
                if (!w.Fields.Any(f => this.DoNamesMatch(f, readerField)))
                {
                    var newField = new RecordField(
                        readerField.NamedEntityAttributes,
                        readerField.TypeSchema,
                        readerField.Order,
                        readerField.HasDefaultValue,
                        readerField.DefaultValue,
                        readerField.MemberInfo,
                        startPosition++)
                    {
                        UseDefaultValue = true
                    };

                    fieldsToAdd.Add(newField);
                }
            }

            if (r.RuntimeType == typeof(AvroRecord) &&
                r.Fields.Any(rf => !rf.HasDefaultValue && !w.Fields.Any(wf => this.DoNamesMatch(wf, rf))))
            {
                throw new SerializationException(
                    string.Format(
                    CultureInfo.InvariantCulture,
                    "Fields without default values found in type '{0}'. Not corresponding writer fields found.",
                    r.RuntimeType));
            }
            return fieldsToAdd;
        }
        private TypeSchema BuildCore(RecordSchema w, RecordSchema r)
        {
            if (!this.DoNamesMatch(w, r))
            {
                return null;
            }

            if (this.visited.ContainsKey(w))
            {
                return this.visited[w];
            }

            var schema = new RecordSchema(
                new NamedEntityAttributes(new SchemaName(w.Name, w.Namespace), w.Aliases, w.Doc),
                r.RuntimeType);

            this.visited.Add(w, schema);

            var fields = this.BuildWriterFields(w, r);
            fields.AddRange(this.BuildReaderFields(w, r, fields.Count));
            fields.Sort((f1, f2) => f1.Position.CompareTo(f2.Position));
            fields.ForEach(schema.AddField);
            return schema;
        }
예제 #16
0
        /// <summary>
        /// Sets the fields.
        /// </summary>
        /// <param name="record">
        /// The record.
        /// </param>
        /// <param name="fields">
        /// The fields.
        /// </param>
        public static void SetFields(RecordSchema record, IEnumerable<RecordField> fields)
        {
            if (record == null)
            {
                throw new ArgumentNullException("record");
            }

            if (fields == null)
            {
                throw new ArgumentNullException("fields");
            }

            if (record.Fields.Count != 0)
            {
                throw new InvalidOperationException("Fields can be set only on empty record.");
            }

            int fieldPosition = 0;
            foreach (var field in fields)
            {
                record.AddField(new RecordField(field.NamedEntityAttributes, field.TypeSchema, field.Order, field.HasDefaultValue, field.DefaultValue, field.MemberInfo, fieldPosition++));
            }
        }