예제 #1
0
        /// <summary>
        /// Static function to return instance of the union schema
        /// </summary>
        /// <param name="jarr">JSON object for the union schema</param>
        /// <param name="names">list of named schemas already read</param>
        /// <param name="encspace">enclosing namespace of the schema</param>
        /// <returns>new UnionSchema object</returns>
        internal static UnionSchema NewInstance(JArray jarr, PropertyMap props, SchemaNames names, string encspace)
        {
            List <Schema> schemas = new List <Schema>();
            IDictionary <string, string> uniqueSchemas = new Dictionary <string, string>();

            foreach (JToken jvalue in jarr)
            {
                Schema unionType = ParseJson(jvalue, names, encspace);
                if (null == unionType)
                {
                    throw new SchemaParseException("Invalid JSON in union" + jvalue);
                }

                string name = unionType.Name;
                if (uniqueSchemas.ContainsKey(name))
                {
                    throw new SchemaParseException("Duplicate type in union: " + name);
                }

                uniqueSchemas.Add(name, name);
                schemas.Add(unionType);
            }

            return(new UnionSchema(schemas, props));
        }
예제 #2
0
        /// <summary>
        /// Writes the Field class in JSON format
        /// </summary>
        /// <param name="writer">JSON writer</param>
        /// <param name="names">list of named schemas already written</param>
        /// <param name="encspace">enclosing namespace for the field</param>
        protected internal void WriteJson(JsonTextWriter writer, SchemaNames names, string encspace)
        {
            writer.WriteStartObject();
            JsonHelper.WriteIfNotNullOrEmpty(writer, "name", Name);
            JsonHelper.WriteIfNotNullOrEmpty(writer, "doc", Documentation);

            if (null != DefaultValue)
            {
                writer.WritePropertyName("default");
                DefaultValue.WriteTo(writer, null);
            }
            if (null != Schema)
            {
                writer.WritePropertyName("type");
                Schema.WriteJson(writer, names, encspace);
            }

            if (null != Props)
            {
                Props.WriteJson(writer);
            }

            if (null != Aliases)
            {
                writer.WritePropertyName("aliases");
                writer.WriteStartArray();
                foreach (string name in Aliases)
                {
                    writer.WriteValue(name);
                }
                writer.WriteEndArray();
            }

            writer.WriteEndObject();
        }
예제 #3
0
        /// <summary>
        /// Creates a new field for the record
        /// </summary>
        /// <param name="jfield">JSON object for the field</param>
        /// <param name="pos">position number of the field</param>
        /// <param name="names">list of named schemas already read</param>
        /// <param name="encspace">enclosing namespace of the records schema</param>
        /// <returns>new Field object</returns>
        private static Field CreateField(JToken jfield, int pos, SchemaNames names, string encspace)
        {
            var name = JsonHelper.GetRequiredString(jfield, "name");
            var doc  = JsonHelper.GetOptionalString(jfield, "doc");

            var jorder = JsonHelper.GetOptionalString(jfield, "order");

            Field.SortOrder sortorder = Field.SortOrder.Ignore;
            if (null != jorder)
            {
                sortorder = (Field.SortOrder)Enum.Parse(typeof(Field.SortOrder), jorder, true);
            }

            var aliases      = Field.GetAliases(jfield);
            var props        = JsonHelper.GetProperties(jfield);
            var defaultValue = jfield["default"];

            JToken jtype = jfield["type"];

            if (null == jtype)
            {
                throw new SchemaParseException("'type' was not found for field: " + name);
            }
            var schema = ParseJson(jtype, names, encspace);

            return(new Field(schema, name, aliases, pos, doc, defaultValue, sortorder, props));
        }
예제 #4
0
 /// <summary>
 /// Writes schema object in JSON format
 /// </summary>
 /// <param name="writer">JSON writer</param>
 /// <param name="names">list of named schemas already written</param>
 /// <param name="encspace">enclosing namespace of the schema</param>
 protected internal virtual void WriteJson(JsonTextWriter writer, SchemaNames names, string encspace)
 {
     WriteStartObject(writer);
     WriteJsonFields(writer, names, encspace);
     if (null != Props)
     {
         Props.WriteJson(writer);
     }
     writer.WriteEndObject();
 }
예제 #5
0
 /// <summary>
 /// Writes union schema in JSON format
 /// </summary>
 /// <param name="writer">JSON writer</param>
 /// <param name="names">list of named schemas already written</param>
 /// <param name="encspace">enclosing namespace of the schema</param>
 protected internal override void WriteJson(JsonTextWriter writer, SchemaNames names,
                                            string encspace)
 {
     writer.WriteStartArray();
     foreach (Schema schema in Schemas)
     {
         schema.WriteJson(writer, names, encspace);
     }
     writer.WriteEndArray();
 }
예제 #6
0
        /// <summary>
        /// Static class to return a new instance of ArraySchema
        /// </summary>
        /// <param name="token">JSON object for the array schema</param>
        /// <param name="props"></param>
        /// <param name="names">list of named schemas already parsed</param>
        /// <param name="encspace">enclosing namespace for the array schema</param>
        /// <returns></returns>
        internal static ArraySchema NewInstance(JToken token, PropertyMap props, SchemaNames names, string encspace)
        {
            JToken jitem = token["items"];

            if (jitem == null)
            {
                throw new BaijiTypeException("Array does not have 'items'");
            }
            return(new ArraySchema(ParseJson(jitem, names, encspace), props));
        }
예제 #7
0
        /// <summary>
        /// Static function to return new instance of map schema
        /// </summary>
        /// <param name="jtok">JSON object for the map schema</param>
        /// <param name="names">list of named schemas already read</param>
        /// <param name="encspace">enclosing namespace of the map schema</param>
        /// <returns></returns>
        internal static MapSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace)
        {
            JToken jvalue = jtok["values"];

            if (null == jvalue)
            {
                throw new BaijiTypeException("Map does not have 'values'");
            }

            return(new MapSchema(ParseJson(jvalue, names, encspace), props));
        }
예제 #8
0
        /// <summary>
        /// Static function to return new instance of the record schema
        /// </summary>
        /// <param name="jtok">JSON object for the record schema</param>
        /// <param name="props"></param>
        /// <param name="names">list of named schema already read</param>
        /// <param name="encspace">enclosing namespace of the records schema</param>
        /// <returns>new RecordSchema object</returns>
        internal static RecordSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names,
                                                 string encspace)
        {
            bool   request = false;
            JToken jfields = jtok["fields"]; // normal record

            if (null == jfields)
            {
                jfields = jtok["request"]; // anonymous record from messages
                if (null != jfields)
                {
                    request = true;
                }
            }
            if (null == jfields)
            {
                throw new SchemaParseException("'fields' cannot be null for record");
            }
            if (jfields.Type != JTokenType.Array)
            {
                throw new SchemaParseException("'fields' not an array for record");
            }

            var name          = GetName(jtok, encspace);
            var aliases       = GetAliases(jtok, name.Space, name.EncSpace);
            var doc           = JsonHelper.GetOptionalString(jtok, "doc");
            var fields        = new List <Field>();
            var fieldMap      = new Dictionary <string, Field>();
            var fieldAliasMap = new Dictionary <string, Field>();
            var result        = new RecordSchema(name, doc, aliases, props, fields, request, fieldMap, fieldAliasMap, names);

            int fieldPos = 0;

            foreach (JObject jfield in jfields)
            {
                string fieldName = JsonHelper.GetRequiredString(jfield, "name");
                Field  field     = CreateField(jfield, fieldPos++, names, name.Namespace);
                // add record namespace for field look up
                fields.Add(field);
                AddToFieldMap(fieldMap, fieldName, field);
                AddToFieldMap(fieldAliasMap, fieldName, field);

                if (null != field.Aliases)
                // add aliases to field lookup map so reader function will find it when writer field name appears only as an alias on the reader field
                {
                    foreach (string alias in field.Aliases)
                    {
                        AddToFieldMap(fieldAliasMap, alias, field);
                    }
                }
            }
            return(result);
        }
예제 #9
0
 /// <summary>
 /// Writes enum schema in JSON format
 /// </summary>
 /// <param name="writer">JSON writer</param>
 /// <param name="names">list of named schema already written</param>
 /// <param name="encspace">enclosing namespace of the enum schema</param>
 protected internal override void WriteJsonFields(JsonTextWriter writer,
                                                  SchemaNames names, string encspace)
 {
     base.WriteJsonFields(writer, names, encspace);
     writer.WritePropertyName("symbols");
     writer.WriteStartArray();
     foreach (string s in Symbols)
     {
         writer.WriteValue(s);
     }
     writer.WriteEndArray();
 }
예제 #10
0
 /// <summary>
 /// Constructor for the record schema
 /// </summary>
 /// <param name="name">name of the record schema</param>
 /// <param name="doc"></param>
 /// <param name="aliases">list of aliases for the record name</param>
 /// <param name="props"></param>
 /// <param name="fields">list of fields for the record</param>
 /// <param name="request">true if this is an anonymous record with 'request' instead of 'fields'</param>
 /// <param name="fieldMap">map of field names and field objects</param>
 /// <param name="fieldAliasMap">map of field aliases and field objects</param>
 /// <param name="names">list of named schema already read</param>
 private RecordSchema(SchemaName name, string doc, IList <SchemaName> aliases, PropertyMap props,
                      List <Field> fields, bool request, IDictionary <string, Field> fieldMap,
                      IDictionary <string, Field> fieldAliasMap, SchemaNames names)
     : base(SchemaType.Record, name, doc, aliases, props, names)
 {
     if (!request && null == name.Name)
     {
         throw new SchemaParseException("name cannot be null for record schema.");
     }
     Fields            = fields;
     this._request     = request;
     _fieldLookup      = fieldMap;
     _fieldAliasLookup = fieldAliasMap;
 }
예제 #11
0
 /// <summary>
 /// Constructor for named schema class
 /// </summary>
 /// <param name="type">schema type</param>
 /// <param name="name">name</param>
 /// <param name="aliases"></param>
 /// <param name="doc"></param>
 /// <param name="props"></param>
 /// <param name="names">list of named schemas already read</param>
 protected NamedSchema(SchemaType type, SchemaName name, string doc, IList <SchemaName> aliases, PropertyMap props,
                       SchemaNames names)
     : base(type, props)
 {
     SchemaName   = name;
     Doc          = doc;
     this.aliases = aliases;
     if (null != name.Name) // Added this check for anonymous records inside Message
     {
         if (!names.Add(name, this))
         {
             throw new BaijiException("Duplicate schema name " + name.Fullname);
         }
     }
 }
예제 #12
0
 /// <summary>
 /// Writes the schema name in JSON format
 /// </summary>
 /// <param name="writer">JSON writer</param>
 /// <param name="names">list of named schemas already written</param>
 /// <param name="encspace">enclosing namespace of the schema</param>
 internal void WriteJson(JsonTextWriter writer, SchemaNames names, string encspace)
 {
     if (null == Name)
     {
         return;
     }
     JsonHelper.WriteIfNotNullOrEmpty(writer, "name", Name);
     if (!string.IsNullOrEmpty(Space))
     {
         JsonHelper.WriteIfNotNullOrEmpty(writer, "namespace", Space);
     }
     else if (!string.IsNullOrEmpty(EncSpace)) // need to put enclosing name space for code generated classes
     {
         JsonHelper.WriteIfNotNullOrEmpty(writer, "namespace", EncSpace);
     }
 }
예제 #13
0
        /// <summary>
        /// Parses a JSON string to create a new schema object
        /// </summary>
        /// <param name="json">JSON string</param>
        /// <param name="names">list of named schemas already read</param>
        /// <param name="encspace">enclosing namespace of the schema</param>
        /// <returns>new Schema object</returns>
        internal static Schema Parse(string json, SchemaNames names, string encspace)
        {
            Schema sc = PrimitiveSchema.NewInstance(json);

            if (null != sc)
            {
                return(sc);
            }

            try
            {
                bool       isArray = json.StartsWith("[") && json.EndsWith("]");
                JContainer j       = isArray ? (JContainer)JArray.Parse(json) : (JContainer)JObject.Parse(json);
                return(ParseJson(j, names, encspace));
            }
            catch (JsonSerializationException ex)
            {
                throw new SchemaParseException("Could not parse. " + ex.Message + Environment.NewLine + json);
            }
        }
예제 #14
0
        /// <summary>
        /// Static function to return a new instance of the named schema
        /// </summary>
        /// <param name="jo">JSON object of the named schema</param>
        /// <param name="props"></param>
        /// <param name="names">list of named schemas already read</param>
        /// <param name="encspace">enclosing namespace of the named schema</param>
        /// <returns></returns>
        internal static NamedSchema NewInstance(JObject jo, PropertyMap props, SchemaNames names, string encspace)
        {
            string type = JsonHelper.GetRequiredString(jo, "type");

            switch (type)
            {
            case "enum":
                return(EnumSchema.NewInstance(jo, props, names, encspace));

            case "record":
                return(RecordSchema.NewInstance(jo, props, names, encspace));

            default:
                NamedSchema result;
                if (names.TryGetValue(type, null, encspace, out result))
                {
                    return(result);
                }
                return(null);
            }
        }
예제 #15
0
        /// <summary>
        /// Writes named schema in JSON format
        /// </summary>
        /// <param name="writer">JSON writer</param>
        /// <param name="names">list of named schemas already written</param>
        /// <param name="encspace">enclosing namespace of the named schema</param>
        protected internal override void WriteJsonFields(JsonTextWriter writer, SchemaNames names, string encspace)
        {
            SchemaName.WriteJson(writer, names, encspace);

            if (string.IsNullOrEmpty(Doc))
            {
                writer.WritePropertyName("doc");
                writer.WriteValue(Doc);
            }

            if (null != aliases)
            {
                writer.WritePropertyName("aliases");
                writer.WriteStartArray();
                foreach (SchemaName name in aliases)
                {
                    string fullname = (null != name.Space) ? name.Space + "." + name.Name : name.Name;
                    writer.WriteValue(fullname);
                }
                writer.WriteEndArray();
            }
        }
예제 #16
0
 /// <summary>
 /// Writes named schema in JSON format
 /// </summary>
 /// <param name="writer">JSON writer</param>
 /// <param name="names">list of named schemas already written</param>
 /// <param name="encspace">enclosing namespace of the named schema</param>
 protected internal override void WriteJson(JsonTextWriter writer, SchemaNames names, string encspace)
 {
     if (!names.Add(this))
     {
         // schema is already in the list, write name only
         SchemaName schemaName = SchemaName;
         string     name;
         if (schemaName.Namespace != encspace)
         {
             name = schemaName.Namespace + "." + schemaName.Name;
             // we need to add the qualifying namespace of the target schema if it's not the same as current namespace
         }
         else
         {
             name = schemaName.Name;
         }
         writer.WriteValue(name);
     }
     else
     {
         // schema is not in the list, write full schema definition
         base.WriteJson(writer, names, encspace);
     }
 }
예제 #17
0
        /// <summary>
        /// Writes the records schema in JSON format
        /// </summary>
        /// <param name="writer">JSON writer</param>
        /// <param name="names">list of named schemas already written</param>
        /// <param name="encspace">enclosing namespace of the record schema</param>
        protected internal override void WriteJsonFields(JsonTextWriter writer, SchemaNames names, string encspace)
        {
            base.WriteJsonFields(writer, names, encspace);

            // we allow reading for empty fields, so writing of records with empty fields are allowed as well
            if (_request)
            {
                writer.WritePropertyName("request");
            }
            else
            {
                writer.WritePropertyName("fields");
            }
            writer.WriteStartArray();

            if (null != Fields && Fields.Count > 0)
            {
                foreach (Field field in this)
                {
                    field.WriteJson(writer, names, Namespace); // use the namespace of the record for the fields
                }
            }
            writer.WriteEndArray();
        }
예제 #18
0
 /// <summary>
 /// Writes primitive schema in JSON format
 /// </summary>
 /// <param name="w"></param>
 /// <param name="names"></param>
 /// <param name="encspace"></param>
 protected internal override void WriteJson(JsonTextWriter w, SchemaNames names, string encspace)
 {
     w.WriteValue(Name);
 }
예제 #19
0
 /// <summary>
 /// Writes map schema in JSON format
 /// </summary>
 /// <param name="writer">JSON writer</param>
 /// <param name="names">list of named schemas already written</param>
 /// <param name="encspace">enclosing namespace of the map schema</param>
 protected internal override void WriteJsonFields(JsonTextWriter writer, SchemaNames names, string encspace)
 {
     writer.WritePropertyName("values");
     ValueSchema.WriteJson(writer, names, encspace);
 }
예제 #20
0
 /// <summary>
 /// Default implementation for writing schema properties in JSON format
 /// </summary>
 /// <param name="writer">JSON writer</param>
 /// <param name="names">list of named schemas already written</param>
 /// <param name="encspace">enclosing namespace of the schema</param>
 protected internal virtual void WriteJsonFields(JsonTextWriter writer, SchemaNames names, string encspace)
 {
 }
예제 #21
0
        /// <summary>
        /// Static method to return new instance of schema object
        /// </summary>
        /// <param name="jtok">JSON object</param>
        /// <param name="names">list of named schemas already read</param>
        /// <param name="encspace">enclosing namespace of the schema</param>
        /// <returns>new Schema object</returns>
        internal static Schema ParseJson(JToken jtok, SchemaNames names, string encspace)
        {
            if (null == jtok)
            {
                throw new ArgumentNullException("jtok", "jtok cannot be null.");
            }

            if (jtok.Type == JTokenType.String)
            // primitive schema with no 'type' property or primitive or named type of a record field
            {
                string value = (string)jtok;

                PrimitiveSchema ps = PrimitiveSchema.NewInstance(value);
                if (null != ps)
                {
                    return(ps);
                }

                NamedSchema schema = null;
                if (names.TryGetValue(value, null, encspace, out schema))
                {
                    return(schema);
                }

                throw new SchemaParseException("Undefined name: " + value);
            }

            if (jtok is JArray) // union schema with no 'type' property or union type for a record field
            {
                return(UnionSchema.NewInstance(jtok as JArray, null, names, encspace));
            }

            if (jtok is JObject) // JSON object with open/close parenthesis, it must have a 'type' property
            {
                JObject jo = jtok as JObject;

                JToken jtype = jo["type"];
                if (null == jtype)
                {
                    throw new SchemaParseException("Property type is required");
                }

                var props = JsonHelper.GetProperties(jtok);

                if (jtype.Type == JTokenType.String)
                {
                    string type = (string)jtype;

                    if (type.Equals("array"))
                    {
                        return(ArraySchema.NewInstance(jtok, props, names, encspace));
                    }
                    if (type.Equals("map"))
                    {
                        return(MapSchema.NewInstance(jtok, props, names, encspace));
                    }

                    Schema schema = PrimitiveSchema.NewInstance((string)type, props);
                    if (null != schema)
                    {
                        return(schema);
                    }

                    return(NamedSchema.NewInstance(jo, props, names, encspace));
                }
                else if (jtype.Type == JTokenType.Array)
                {
                    return(UnionSchema.NewInstance(jtype as JArray, props, names, encspace));
                }
            }
            throw new BaijiTypeException("Invalid JSON for schema: " + jtok);
        }
예제 #22
0
 /// <summary>
 /// Constructor for enum schema
 /// </summary>
 /// <param name="name">name of enum</param>
 /// <param name="doc"></param>
 /// <param name="aliases">list of aliases for the name</param>
 /// <param name="symbols">list of enum symbols</param>
 /// <param name="symbolMap">map of enum symbols and value</param>
 /// <param name="names">list of named schema already read</param>
 private EnumSchema(SchemaName name, string doc, IList <SchemaName> aliases, IList <string> symbols,
                    IDictionary <string, int?[]> symbolMap, PropertyMap props, SchemaNames names)
     : base(SchemaType.Enumeration, name, doc, aliases, props, names)
 {
     if (null == name.Name)
     {
         throw new SchemaParseException("name cannot be null for enum schema.");
     }
     Symbols        = symbols;
     this.symbolMap = symbolMap;
 }
예제 #23
0
        /// <summary>
        /// Static function to return new instance of EnumSchema
        /// </summary>
        /// <param name="token">JSON object for enum schema</param>
        /// <param name="names">list of named schema already parsed in</param>
        /// <param name="encspace">enclosing namespace for the enum schema</param>
        /// <returns>new instance of enum schema</returns>
        internal static EnumSchema NewInstance(JToken token, PropertyMap props, SchemaNames names, string encspace)
        {
            SchemaName name    = GetName(token, encspace);
            var        aliases = GetAliases(token, name.Space, name.EncSpace);
            var        doc     = JsonHelper.GetOptionalString(token, "doc");

            JArray jsymbols = token["symbols"] as JArray;

            if (null == jsymbols)
            {
                throw new SchemaParseException("Enum has no symbols: " + name);
            }

            var symbols = new List <string>();
            IDictionary <string, int?[]> symbolMap = new Dictionary <string, int?[]>();
            int lastValue = -1;

            foreach (JToken jsymbol in jsymbols)
            {
                int?   explicitValue = null;
                int    actualValue;
                string symbol;
                if (jsymbol is JValue)
                {
                    symbol      = (string)((JValue)jsymbol).Value;
                    actualValue = ++lastValue;
                }
                else if (jsymbol is JObject)
                {
                    var symbolObj = (JObject)jsymbol;
                    symbol = symbolObj.Value <string>("name");
                    if (symbol == null)
                    {
                        throw new SchemaParseException("Missing symbol name: " + jsymbol);
                    }
                    JToken valueToken;
                    if (symbolObj.TryGetValue("value", out valueToken))
                    {
                        try
                        {
                            explicitValue = symbolObj.Value <int>("value");
                        }
                        catch (System.Exception)
                        {
                            throw new SchemaParseException("Only integer value is allowed for an enum symbol: " + jsymbol);
                        }
                    }
                    lastValue = actualValue = explicitValue.HasValue ? explicitValue.Value : lastValue + 1;
                }
                else
                {
                    throw new SchemaParseException("Invalid symbol object: " + jsymbol);
                }

                if (symbolMap.ContainsKey(symbol))
                {
                    throw new SchemaParseException("Duplicate symbol: " + symbol);
                }

                symbolMap[symbol] = new [] { explicitValue, actualValue };
                symbols.Add(symbol);
            }
            return(new EnumSchema(name, doc, aliases, symbols, symbolMap, props, names));
        }