/// <summary> /// Populates a property in an object with data from the StepValue. /// </summary> /// <param name="pi">The property of the object which will be populated with the data</param> /// <param name="obj">The object which will be populated</param> /// <param name="sv">The data to insert into the property</param> /// <param name="stepId">The Id of the step data object which provided the data. (required incase of any step referencing)</param> private void populateProperty(PropertyInfo pi, ref object obj, StepValue sv, int stepId ){ if(pi == null) throw new ArgumentNullException("pi"); if(obj == null) throw new ArgumentNullException("obj"); //debugging logger.Debug("Type of object being populated : " + obj.GetType().FullName); logger.Debug("The property being assigned to in the .Net object : " + pi.Name); logger.Debug("The type of values held by that .Net property : " + pi.PropertyType); logger.Debug("STEP token : " + sv.Token); logger.Debug("STEP value : " + sv.Value); logger.Debug("STEP valueType : " + sv.ValueType); switch(sv.Token){ case StepToken.StartEntity: mapObject(pi, ref obj, sv); break; case StepToken.String: mapString(pi, ref obj, sv); break; case StepToken.LineReference: storeLineReference(pi, ref obj, stepId, sv); break; case StepToken.StartArray: mapArray(pi, ref obj, sv, stepId); break; case StepToken.Enumeration: mapEnumeration(pi, ref obj, sv); break; case StepToken.Integer: mapInteger(pi, ref obj, sv); break; case StepToken.Float: mapFloat(pi, ref obj, sv); break; case StepToken.Null: //do nothing, the property value will already be null or default value (if a value type). break; case StepToken.Overridden: //do nothing break; default: throw new NotImplementedException(String.Format(CultureInfo.InvariantCulture, "Failed on attempting to set value of property. This token type is not yet implemented: {0}", sv.Token)); } }
public void AssertInteger(int expectedValue, StepValue actual){ AssertStepValue(StepToken.Integer, typeof(int), expectedValue, actual); }
private void SerializeProperty( IStepWriter writer, StepValue sv){ if(writer == null) throw new ArgumentNullException("writer"); switch(sv.Token){ case StepToken.StartArray: //TODO assert that sv.ValueType.Equals(typeof(IList<StepValue>) SerializeArray( writer, sv.Value as List<StepValue> ); break; case StepToken.Overridden: writer.WriteOverridden(); break; case StepToken.Enumeration: writer.WriteEnum((string)sv.Value); break; case StepToken.String: writer.WriteValue((string)sv.Value); break; case StepToken.Integer: switch(sv.ValueType.ToString()){ case "System.Int16": writer.WriteValue((System.Int16)sv.Value); break; case "System.Int32": writer.WriteValue((System.Int32)sv.Value); break; case "System.Int64": writer.WriteValue((System.Int64)sv.Value); break; default: throw new StepSerializerException("SerializeProperty(StepWriter, StepValue) has a StepValue of token type Integer, but the ValueType is not an integer"); } break; case StepToken.Float: writer.WriteValue((double)sv.Value); break; case StepToken.Boolean: writer.WriteBool((bool)sv.Value); break; case StepToken.Date: writer.WriteValue(((DateTime)sv.Value).ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture)); break; case StepToken.Null: writer.WriteNull(); break; case StepToken.LineReference: writer.WriteLineReference( (int)sv.Value ); break; case StepToken.StartEntity: logger.Debug("StartEntity : " + ((StepDataObject)sv.Value).ObjectName); SerializeObject(writer, (StepDataObject)sv.Value); break; default: throw new NotImplementedException(String.Format(CultureInfo.InvariantCulture, "SerializeProperty(StepValue) cannot, yet, handle token {0}", sv.Token.ToString())); } }
private void storeLineReference(PropertyInfo pi, ref Object obj, int stepId, StepValue sp, int index){ this._objectLinks.Add(new StepEntityReference(stepId, pi, (int)sp.Value, index)); }
public void AssertStepValue(StepToken expectedToken, Type expectedValueType, object expectedValue, StepValue actual){ Assert.IsNotNull(actual); Assert.AreEqual(expectedToken, actual.Token); Assert.AreEqual(expectedValueType, actual.ValueType); Assert.AreEqual(expectedValue, actual.Value); }
/// <summary> /// Maps a STEP enumeration to a .Net enum /// </summary> /// <param name="pi"></param> /// <param name="obj"></param> /// <param name="sv"></param> private void mapEnumeration(PropertyInfo pi, ref Object obj, StepValue sv){ if(pi == null) throw new ArgumentNullException("pi"); if(obj == null) throw new ArgumentNullException("obj"); if(sv.Value == null) throw new ArgumentNullException("sv.Value"); if(!(sv.Value is string)) throw new ArgumentException("sv.Value should be a type of string"); string spv = sv.Value as string; if(string.IsNullOrEmpty(spv)) throw new ArgumentException("sv.Value should not be null or empty"); spv = spv.ToLower(); Object val; //STEP treats boolean values as enumerations if(pi.PropertyType == typeof(System.Boolean)){ if(spv.Equals("t") || spv.Equals("f")) val = spv.Equals("t"); else throw new FormatException(String.Format(CultureInfo.InvariantCulture, "mapEnumeration found a boolean to parse, but the value was neither 't' nor 'f'. The value was instead {0}", spv)); }else{ //pi.Property type may be Nullable<theTypeWeNeed> Type enumType = Nullable.GetUnderlyingType( pi.PropertyType ); if(enumType == null) enumType = pi.PropertyType; val = Enum.Parse(enumType, spv);//HACK the ToLower may not work in all cases } if(val == null) throw new FormatException(String.Format(CultureInfo.InvariantCulture, "Could not find a suitable value for {0} in Enum type {1}", spv.ToLower(), pi.PropertyType.Name)); pi.SetValue(obj, val, null); }
/// <summary> /// Maps a STEP float to .Net System.Double /// </summary> /// <param name="pi"></param> /// <param name="obj"></param> /// <param name="sv"></param> private void mapFloat(PropertyInfo pi, ref Object obj, StepValue sv){ if(pi == null) throw new ArgumentNullException("pi"); if(obj == null) throw new ArgumentNullException("obj"); if(!(sv.Value is double)) throw new ArgumentException("sv.Value cannot be cast to a double"); pi.SetValue(obj, (double)sv.Value, null); }
public void AssertNestedObject(string expectedName, int expectedNumberOfProperties, StepValue actual){ Assert.IsNotNull(actual); Assert.IsNotNull(actual.Value); Assert.AreEqual(StepToken.StartEntity, actual.Token); Assert.AreEqual(typeof(StepDataObject), actual.ValueType); StepDataObject sdo = actual.Value as StepDataObject; Assert.IsNotNull(sdo); AssertObject(expectedName, expectedNumberOfProperties, sdo); }
public void AssertNull(StepValue actual){ AssertStepValue(StepToken.Null, null, null, actual); }
public void AssertArray(int expectedCount, StepValue actual){ AssertArray(actual); List<StepValue> array = actual.Value as List<StepValue>; Assert.IsNotNull(array); Assert.AreEqual(expectedCount, array.Count); }
public void AssertLineReference(int expectedLineReference, StepValue actual){ AssertStepValue(StepToken.LineReference, typeof(int), expectedLineReference, actual); }
/// <summary> /// Asserts a StepValue is an array and is not null, but does not assert anything of the array contents /// </summary> /// <param name="actual"></param> public void AssertArray(StepValue actual){ Assert.IsNotNull(actual); Assert.AreEqual(StepToken.StartArray, actual.Token); Assert.AreEqual(typeof(List<StepValue>), actual.ValueType); Assert.IsNotNull(actual.Value); }
public void AssertDate(string expectedDate, StepValue actual){ AssertStepValue(StepToken.Date, typeof(DateTime), DateTime.Parse(expectedDate), actual); }
public void AssertString(string expectedValue, StepValue actual){ AssertStepValue(StepToken.String, typeof(string), expectedValue, actual); }
/// <summary> /// Maps a STEP entity to a .Net object /// </summary> /// <param name="pi"></param> /// <param name="obj"></param> /// <param name="sv"></param> private void mapObject(PropertyInfo pi, ref Object obj, StepValue sv){ if(pi == null) throw new ArgumentNullException("pi"); if(obj == null) throw new ArgumentNullException("obj"); if(sv.Value == null) throw new ArgumentNullException("sv.Value"); StepDataObject sdo = sv.Value as StepDataObject; if(sdo == null) throw new ArgumentException("sv.Value is not of type StepDataObject"); Object nestedObj = bindObject(-1, sdo); //as a quirk of the automatically generated schema //nested properties are wrapped in an intermediate class. Object wrappingObj = Activator.CreateInstance(pi.PropertyType); logger.Debug("Attempting to find \"Item\" property for type of " + pi.PropertyType); PropertyInfo wrappingProp = pi.PropertyType.GetProperty("Item", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance); if(wrappingProp == null) throw new StepBindingException("Could not find a suitable property in the wrapping class around a nested object"); wrappingProp.SetValue(wrappingObj, nestedObj, null); //now insert the wrapping object pi.SetValue(obj, wrappingObj, null); }
public void AssertFloat(double expectedValue, StepValue actual){ AssertStepValue(StepToken.Float, typeof(double), expectedValue, actual); }
/// <summary> /// Maps a STEP string to a .Net System.String /// </summary> /// <param name="pi"></param> /// <param name="obj"></param> /// <param name="sv"></param> private void mapString(PropertyInfo pi, ref Object obj, StepValue sv){ if(pi == null) throw new ArgumentNullException("pi"); if(obj == null) throw new ArgumentNullException("obj"); if(sv.Value == null) throw new ArgumentNullException("sv.Value"); if(!(sv.Value is string)) throw new ArgumentException("sv.Value is not of type String"); pi.SetValue(obj, (string)sv.Value, null); }
public void AssertEnum(string expectedValue, StepValue actual){ AssertStepValue(StepToken.Enumeration, typeof(string), expectedValue, actual); }
/// <summary> /// Maps a STEP integer to a .Net System.Int32 /// </summary> /// <param name="pi"></param> /// <param name="obj"></param> /// <param name="sv"></param> private void mapInteger(PropertyInfo pi, ref Object obj, StepValue sv){ if(pi == null) throw new ArgumentNullException("pi"); if(obj == null) throw new ArgumentNullException("obj"); if(!(sv.Value is int)) throw new ArgumentException("sv.Value cannot be cast to an int"); pi.SetValue(obj, (int)sv.Value, null); }
public void AssertBoolean(bool expectedValue, StepValue actual){ AssertStepValue(StepToken.Boolean, typeof(bool), expectedValue, actual); }
/// <summary> /// Maps a STEP array to a .Net array. /// </summary> /// <remarks>The .Net schema often wraps arrays in intermediate objects, and this case is dealt with by the function</remarks> /// <param name="pi">The property of the entity which holds an array</param> /// <param name="obj">The entity as currently constructed</param> /// <param name="sv">The value to be entered into the object</param> /// <param name="stepId">the number of the object as given in the step format being deserialized</param> private void mapArray(PropertyInfo pi, ref Object obj, StepValue sv, int stepId){ if(pi == null) throw new ArgumentNullException("pi"); if(obj == null) throw new ArgumentNullException("obj"); if(sv.Value == null) throw new ArgumentNullException("sv.Value"); IList<StepValue> stepValues = sv.Value as IList<StepValue>; if(stepValues == null) throw new StepBindingException("sv.Value cannot be converted to List<StepValues>"); if(stepValues.Count < 1) return; logger.Debug("Number of items in array : " + stepValues.Count); PropertyInfo arrayProperty = findArrayProperty( pi ); if(arrayProperty == null) throw new StepBindingException(String.Format(CultureInfo.InvariantCulture, "Cannot find a suitable property in the array wrapping type {0} which would hold an array", pi.PropertyType.Name)); Object arrayWrappingObject; //check incase there is an intermediate type if(arrayProperty.Equals(pi)) arrayWrappingObject = obj; else arrayWrappingObject = System.Activator.CreateInstance(pi.PropertyType); //get the array, or create it if it doesn't already exist Array array = (Array)arrayProperty.GetValue(arrayWrappingObject, null); if(array == null) array = Array.CreateInstance( arrayProperty.PropertyType.GetElementType(), stepValues.Count ); if(array.Length != stepValues.Count) throw new StepBindingException(String.Format(CultureInfo.InvariantCulture, "The array length, {0}, is not long enough to hold all the properties, {1}, being mapped to it", array.Length, stepValues.Count)); //iterate through each item and add it to the array. for(int arrayIndex = 0; arrayIndex < stepValues.Count; arrayIndex++){ StepValue svInner = stepValues[arrayIndex]; //debugging logger.Debug("Mapping property in array. Index : " + arrayIndex); logger.Debug("Property being assigned to in the .Net object : " + arrayProperty.Name); logger.Debug("The Type of values held by that .Net property : " + arrayProperty.PropertyType.GetElementType().Name); logger.Debug("STEP token : " + svInner.Token); logger.Debug("STEP value : " + svInner.Value); logger.Debug("STEP valueType : " + svInner.ValueType); switch(svInner.Token){ case StepToken.String: case StepToken.Float: case StepToken.Integer: if(array.GetType().GetElementType().Equals( svInner.ValueType )) array.SetValue(svInner.Value, arrayIndex); else{ //we need to convert/cast the type, and need the conversion operator of the target type to assist with this MethodInfo mi = array.GetType().GetElementType().GetMethod( "op_Implicit", (BindingFlags.Public | BindingFlags.Static), null, new Type[] { svInner.ValueType }, new ParameterModifier[0] ); if(mi == null) throw new NotImplementedException(String.Format(CultureInfo.InvariantCulture, "Cannot convert from a {0} to a type of {1}, as there is no static implicit cast method present on the type we're casting to", svInner.ValueType.Name, array.GetType().GetElementType().Name)); Object parsedValue = mi.Invoke(null, BindingFlags.InvokeMethod | (BindingFlags.Public | BindingFlags.Static), null, new object[] { svInner.Value }, CultureInfo.InvariantCulture); if(parsedValue == null) throw new StepBindingException(String.Format(CultureInfo.InvariantCulture, "Was unable to invoke the conversion operator to convert the value {0}, a type of {1}, to the type {2}", svInner.Value.ToString(), svInner.ValueType.Name, array.GetType().GetElementType().Name)); array.SetValue(parsedValue, arrayIndex); } continue; case StepToken.StartEntity: Object nestedObj = bindObject(-1, svInner.Value as StepDataObject ); array.SetValue(nestedObj, arrayIndex); continue; case StepToken.LineReference: storeLineReference(pi, ref obj, stepId, svInner, arrayIndex); continue; default: throw new NotImplementedException(svInner.Token + " is not yet implemented in mapArray"); } } //now add the array to the array wrapping object arrayProperty.SetValue(arrayWrappingObject, array, null); //if there is a wrapping object, then we need to insert that into the object. if(!arrayProperty.Equals(pi)){ pi.SetValue(obj, arrayWrappingObject, null); } }
public void AssertOverridden(StepValue actual){ AssertStepValue(StepToken.Overridden, null, null, actual); }
public static StepValue CreateArray(params StepValue[] values) { IList <StepValue> valueList = new List <StepValue>(values); return(StepValue.CreateArray(valueList)); }
public List<StepValue> getArray(StepValue stepValueContainingArray){ return stepValueContainingArray.Value as List<StepValue>; }