public override Expression GetExpression(object data, JsonPath currentPath, IExpressionBuilder serializer) { DataTable table = (DataTable) data; ObjectExpression tableExpr = new ObjectExpression(); tableExpr.Add("TableName", serializer.Serialize(table.TableName, currentPath.Append("TableName"))); tableExpr.Add("Columns", GetColumnsExpression(table, currentPath.Append("Columns"), serializer)); tableExpr.Add("Rows", GetRowsExpression(table, currentPath, serializer)); return tableExpr; }
public virtual void Visit(ObjectExpression expression) { OnObjectStart(expression); Visit((ComplexExpressionBase)expression); foreach (KeyValueExpression kv in expression.Properties) { kv.Accept(this); } OnObjectEnd(expression); }
/// <summary> /// Called on an object expression before the properties and constructor arguments are visited /// </summary> /// <param name="expression"></param> public virtual void OnObjectStart(ObjectExpression expression) { }
/// <summary> /// Called on an object expression after the properties and constructor arguments are visited /// </summary> /// <param name="expression"></param> public virtual void OnObjectEnd(ObjectExpression expression) { }
/// <summary> /// Serialize an object implementing IDictionary. The serialized data is similar to a regular /// object, except that the keys of the dictionary are used instead of properties. /// </summary> /// <param name="data">the dictionary object</param> /// <param name="currentPath">object's path</param> /// <param name="serializer">the serializer instance, used to serialize keys and values</param> public override Expression GetExpression(object data, JsonPath currentPath, IExpressionBuilder serializer) { IDictionary dictionary = (IDictionary)data; Type itemType = typeof(object); Type genericDictionary = null; if ((genericDictionary = dictionary.GetType().GetInterface(typeof(IDictionary<,>).Name)) != null) { itemType = genericDictionary.GetGenericArguments()[1]; } ObjectExpression expression = new ObjectExpression(); foreach (DictionaryEntry pair in dictionary) { //may not work in all cases object value = pair.Value; Expression valueExpr = serializer.Serialize(value, currentPath.Append(pair.Key.ToString())); if (value != null && !ReflectionUtils.AreEquivalentTypes(value.GetType(), itemType)) { valueExpr = new CastExpression(value.GetType(), valueExpr); } expression.Add(pair.Key.ToString(), valueExpr); } return expression; }
protected virtual Expression GetColumnExpression(DataColumn dc, JsonPath jsonPath, IExpressionBuilder serializer) { ObjectExpression column = new ObjectExpression(); // just DataType and column for now column.Add("DataType", serializer.Serialize(dc.DataType, jsonPath.Append("DataType"))); column.Add("ColumnName", serializer.Serialize(dc.ColumnName, jsonPath.Append("ColumnName"))); return column; }
/// <summary> /// Creates an json object expression from object data. /// </summary> /// <param name="data">the data to serialize</param> /// <param name="currentPath">current path to the object</param> /// <param name="serializer">serializer instance used to serialize key values</param> /// <returns>json object expression</returns> public override Expression GetExpression(object data, JsonPath currentPath, IExpressionBuilder serializer) { TypeData handler = Config.GetTypeHandler(data.GetType()); ObjectExpression expression = new ObjectExpression(); foreach (IPropertyData prop in handler.Properties) { GenerateItemExpression(data, currentPath, serializer, expression, prop); } return expression; }
/// <summary> /// Constructs a new instance of the object represented by the expression. /// </summary> /// <param name="expression">json object expression</param> /// <param name="deserializer">deserializer for deserializing constructor arguments if any</param> /// <returns>constructed, but unpopulated object</returns> protected virtual object ConstructObject(ObjectExpression expression, IDeserializerHandler deserializer) { TypeData handler = Config.GetTypeHandler(expression.ResultType); // set the default type if none set if (expression.ConstructorArguments.Count > 0) { // old way expects parameters in the constructor list ResolveConstructorTypes(Config, expression); } else { foreach (IPropertyData parameter in handler.ConstructorParameters) { int propLocation = expression.IndexOf(parameter.Alias); if (propLocation >= 0) { Expression arg = expression.Properties[propLocation].ValueExpression; arg.ResultType = parameter.PropertyType; expression.ConstructorArguments.Add(arg); expression.Properties.RemoveAt(propLocation); } else { expression.ConstructorArguments.Add(new NullExpression()); } } } object[] args = new object[expression.ConstructorArguments.Count]; for (int i = 0; i < args.Length; i++) { Expression carg = expression.ConstructorArguments[i]; if (i < handler.ConstructorParameters.Count && handler.ConstructorParameters[i].HasConverter) { TypeConverterExpressionHandler converterHandler = (TypeConverterExpressionHandler)Config.ExpressionHandlers.Find(typeof(TypeConverterExpressionHandler)); args[i] = converterHandler.Evaluate(carg, deserializer, handler.ConstructorParameters[i].TypeConverter); } else { args[i] = deserializer.Evaluate(carg); } } object result = handler.CreateInstance(args); expression.OnObjectConstructed(result); return result; }
/// <summary> /// Generates an expression for an item and adds it to the object /// </summary> /// <param name="data">the item being serialized</param> /// <param name="currentPath">the current path to the object</param> /// <param name="serializer">serializer instance</param> /// <param name="expression">the object expression</param> /// <param name="prop">the property being serialized</param> protected virtual void GenerateItemExpression(object data, JsonPath currentPath, IExpressionBuilder serializer, ObjectExpression expression, IPropertyData prop) { object value = prop.GetValue(data); if (!prop.ShouldWriteValue(this.Config, value)) return; Expression valueExpr; if (prop.HasConverter) { valueExpr = serializer.Serialize(value, currentPath.Append(prop.Alias), prop.TypeConverter); } else { valueExpr = serializer.Serialize(value, currentPath.Append(prop.Alias)); } if (value != null && !ReflectionUtils.AreEquivalentTypes(value.GetType(), prop.PropertyType)) { valueExpr = new CastExpression(value.GetType(), valueExpr); } expression.Add(prop.Alias, valueExpr); }
/// <summary> /// Resolves and updates the types of any constructor arguments /// </summary> /// <param name="context">serialization context</param> /// <param name="expression">object expression</param> protected static void ResolveConstructorTypes(IConfiguration config, ObjectExpression expression) { TypeData handler = config.GetTypeHandler(expression.ResultType); Type[] definedTypes = GetConstructorParameterTypes(handler.ConstructorParameters); CtorArgTypeResolver resolver = new CtorArgTypeResolver(expression, config, definedTypes); Type[] resolvedTypes = resolver.ResolveTypes(); for (int i = 0; i < resolvedTypes.Length; i++) { if (resolvedTypes[i] != null) expression.ConstructorArguments[i].ResultType = resolvedTypes[i]; } }
public void VisitObject(ObjectExpression expression) { Visit(typeof(ComplexExpressionBase), expression); if (_expr != null) return; // found it string key = _refID.Top; foreach (KeyValueExpression exp in expression.Properties) { if (exp.Key == key) { Visit(exp); return; } } // if we get here we didn't find it throw new Exception("Unable to resolve reference: " + _refID); }
/// <summary> /// Parses a javascript object /// </summary> /// <returns></returns> private ObjectExpression ParseObject() { Token tok = ReadToken(); Debug.Assert(tok == LBraceToken); ObjectExpression value = new ObjectExpression() { LineNumber = tok.linenumber, CharacterPosition = tok.position }; Expression item; bool first = true; while (ReadAhead(CommaToken, RBraceToken, new ExpressionMethod(ParseKeyValue), out item, ref first)) { value.Add((KeyValueExpression)item); } return value; }
/// <summary> /// Parses a constructor expression /// </summary> /// <returns>complex expression</returns> /// <example> /// new MyType("arg1", "arg2") /// new MyType("argA", "argB") { "argC": "C", "argD": "D" } /// </example> private Expression ParseConstructedObject() { Token tok = ReadToken(); // should be the new keyword Debug.Assert(tok == NewToken); Type t = ParseTypeSpecifier(); int line = tok.linenumber; int pos = tok.position; tok = ReadToken(); RequireToken(LParenToken, tok, "Missing constructor arguments"); Expression arg; List<Expression> ConstructorArgs = new List<Expression>(); bool first = true; while (ReadAhead(CommaToken, RParenToken, new ExpressionMethod(ParseExpression), out arg, ref first)) { ConstructorArgs.Add(arg); } ComplexExpressionBase value = null; if (PeekToken() == LSquareToken || PeekToken() == LBraceToken) { value = (ComplexExpressionBase) ParseExpression(); } else { value = new ObjectExpression(); } value.ResultType = t; value.ConstructorArguments = ConstructorArgs; value.LineNumber = line; value.CharacterPosition = pos; // insert Cast to keep type from being overwritten return new CastExpression(t,value); }
public void Visit(ObjectExpression objExpr) { VisitComplex(objExpr); foreach (KeyValueExpression item in objExpr.Properties) Visit(item); }