private FixedSchema ParseFixedType(JObject type, NamedSchema parent) { var name = type.RequiredProperty<string>(Token.Name); var nspace = this.GetNamespace(type, parent, name); var fixedName = new SchemaName(name, nspace); var size = type.RequiredProperty<int>(Token.Size); if (size <= 0) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Only positive size of fixed values allowed: '{0}'.", size)); } var aliases = this.GetAliases(type, fixedName.Namespace); var attributes = new NamedEntityAttributes(fixedName, aliases, string.Empty); var customAttributes = type.GetAttributesNotIn(StandardProperties.Record); var result = new FixedSchema(attributes, size, typeof(byte[]), customAttributes); return result; }
/// <summary> /// Parses the primitive type schema. /// </summary> /// <param name="token">The token.</param> /// <param name="usingTypeName">Will use this type name for creating the primitive type.</param> /// <returns>Schema internal representation.</returns> private TypeSchema ParsePrimitiveTypeFromObject(JObject token, string usingTypeName = null) { if (usingTypeName == null) { usingTypeName = token.RequiredProperty<string>(Token.Type); } var customAttributes = token.GetAttributesNotIn(StandardProperties.Primitive); return this.CreatePrimitiveTypeSchema(usingTypeName, customAttributes); }
/// <summary> /// Parses the record field. /// </summary> /// <param name="field">The field.</param> /// <param name="parent">The parent schema.</param> /// <param name="namedSchemas">The named schemas.</param> /// <param name="position">The position.</param> /// <returns> /// Schema internal representation. /// </returns> /// <exception cref="System.Runtime.Serialization.SerializationException">Thrown when <paramref name="field"/> is not valid or when sort order is not valid.</exception> private RecordField ParseRecordField(JObject field, NamedSchema parent, Dictionary<string, NamedSchema> namedSchemas, int position) { var name = field.RequiredProperty<string>(Token.Name); var doc = field.OptionalProperty<string>(Token.Doc); var order = field.OptionalProperty<string>(Token.Order); var aliases = this.GetAliases(field, parent.FullName); var fieldType = field[Token.Type]; if (fieldType == null) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Record field schema '{0}' has no type.", field)); } TypeSchema type = this.Parse(fieldType, parent, namedSchemas); object defaultValue = null; bool hasDefaultValue = field[Token.Default] != null; if (hasDefaultValue) { var objectParser = new JsonObjectParser(); defaultValue = objectParser.Parse(type, field[Token.Default].ToString()); } var orderValue = SortOrder.Ascending; if (!string.IsNullOrEmpty(order)) { if (!SortValue.ContainsKey(order.ToUpperInvariant())) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Invalid sort order of the field '{0}'.", order)); } orderValue = SortValue[order.ToUpperInvariant()]; } var fieldName = new SchemaName(name); var attributes = new NamedEntityAttributes(fieldName, aliases, doc); return new RecordField(attributes, type, orderValue, hasDefaultValue, defaultValue, null, position); }
/// <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; }
/// <summary> /// Parses a JSON object representing an Avro enumeration to a <see cref="Microsoft.Hadoop.Avro.Schema.EnumSchema"/>. /// </summary> /// <param name="enumeration">The JSON token that represents the enumeration.</param> /// <param name="parent">The parent schema.</param> /// <param name="namedSchemas">The named schemas.</param> /// <returns> /// Instance of <see cref="TypeSchema" /> containing IR of the enumeration. /// </returns> /// <exception cref="System.Runtime.Serialization.SerializationException">Thrown when <paramref name="enumeration"/> contains invalid symbols.</exception> private TypeSchema ParseEnumType(JObject enumeration, NamedSchema parent, Dictionary<string, NamedSchema> namedSchemas) { var name = enumeration.RequiredProperty<string>(Token.Name); var nspace = this.GetNamespace(enumeration, parent, name); var enumName = new SchemaName(name, nspace); var doc = enumeration.OptionalProperty<string>(Token.Doc); var aliases = this.GetAliases(enumeration, enumName.Namespace); var attributes = new NamedEntityAttributes(enumName, aliases, doc); List<string> symbols = enumeration.OptionalArrayProperty( Token.Symbols, (symbol, index) => { if (symbol.Type != JTokenType.String) { throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Expected an enum symbol of type string however the type of the symbol is '{0}'.", symbol.Type)); } return (string)symbol; }); Dictionary<string, string> customAttributes = enumeration.GetAttributesNotIn(StandardProperties.Enumeration); var result = new EnumSchema(attributes, typeof(AvroEnum), customAttributes); namedSchemas.Add(result.FullName, result); symbols.ForEach(result.AddSymbol); return result; }
/// <summary> /// Parses the JSON object. /// </summary> /// <param name="token">The object.</param> /// <param name="parent">The parent schema.</param> /// <param name="namedSchemas">The schemas.</param> /// <returns> /// Schema internal representation. /// </returns> /// <exception cref="System.Runtime.Serialization.SerializationException">Thrown when JSON schema type is invalid.</exception> private TypeSchema ParseJsonObject(JObject token, NamedSchema parent, Dictionary<string, NamedSchema> namedSchemas) { JToken tokenType = token[Token.Type]; if (tokenType.Type == JTokenType.String) { var type = token.RequiredProperty<string>(Token.Type); if (PrimitiveRuntimeType.ContainsKey(type)) { return this.ParsePrimitiveTypeFromObject(token); } switch (type) { case Token.Record: return this.ParseRecordType(token, parent, namedSchemas); case Token.Enum: return this.ParseEnumType(token, parent, namedSchemas); case Token.Array: return this.ParseArrayType(token, parent, namedSchemas); case Token.Map: return this.ParseMapType(token, parent, namedSchemas); case Token.Fixed: return this.ParseFixedType(token, parent); default: throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Invalid type specified: '{0}'.", type)); } } if (tokenType.Type == JTokenType.Array) { return this.ParseUnionType(tokenType as JArray, parent, namedSchemas); } throw new SerializationException( string.Format(CultureInfo.InvariantCulture, "Invalid type specified: '{0}'.", tokenType)); }