private StringBuilder GenerateMissingMandatoryValuesReport(ConcreteModel model, Assembly assembly) { StringBuilder report = new StringBuilder(); //extract names Dictionary <string, string> names = GetNames(model.ModelMap, assembly); foreach (KeyValuePair <string, SortedDictionary <string, object> > kv in model.ModelMap) { Type type = assembly.GetType(kv.Key); List <PropertyInfo> pInfoList = GetIsMandatoryProperties(type); foreach (PropertyInfo pInfo in pInfoList) { string propertyName = pInfo.Name.Substring("is".Length); propertyName = propertyName.Substring(0, propertyName.Length - "mandatory".Length); PropertyInfo hasValueProp = type.GetProperty(propertyName + "HasValue"); bool firstOccurance = true; foreach (KeyValuePair <string, object> idObjectPair in kv.Value) { if (idObjectPair.Value != null) { if (!(bool)hasValueProp.GetValue(idObjectPair.Value, null)) { //no value so add to report if (firstOccurance) { report.AppendLine("[WARNING] Missing mandatory property " + type.Name + "." + propertyName + " on following entities:"); if (this.missingValuesMap.ContainsKey(idObjectPair.Key)) { if (!this.missingValuesMap[idObjectPair.Key].Contains(propertyName)) { this.missingValuesMap[idObjectPair.Key].Add(propertyName); } } else { this.missingValuesMap.Add(idObjectPair.Key, new List <string>() { propertyName }); } firstOccurance = false; } if (this.missingValuesMap.ContainsKey(idObjectPair.Key)) { if (!this.missingValuesMap[idObjectPair.Key].Contains(propertyName)) { this.missingValuesMap[idObjectPair.Key].Add(propertyName); } } else { this.missingValuesMap.Add(idObjectPair.Key, new List <string>() { propertyName }); } report.AppendLine("\t - ID: " + idObjectPair.Key + ";" + GetName(names, idObjectPair.Key)); } } } } } return(report); }
/// <summary> /// Method adds reference to list on property prop /// </summary> /// <param name="list">list that reference will be added to</param> /// <param name="att">attribute containing information about reference</param> /// <param name="prop">property containing list</param> private void AddReferenceToList(CIMObject element, ref IList list, string attValue, PropertyInfo prop, ConcreteModel model) { if (!string.IsNullOrEmpty(attValue)) { Type referencedType = prop.PropertyType; string referencedID = StringManipulationManager.ExtractAllAfterSeparator(attValue, StringManipulationManager.SeparatorSharp); string refType = referencedType.ToString(); if (referencedType.IsGenericType) { refType = referencedType.GetGenericArguments()[0].ToString(); } //DataTypes? what about them if in list - should be a way to determine object referencedObject = model.GetObjectByID(referencedID); if (referencedObject != null) { try { list.Add(referencedObject); } catch { OnMessage("Unsuccessful adding item to list on property: " + prop.DeclaringType + "." + prop.Name + ", elements ID:" + element.ID + " Referenced: " + refType + ", ID: " + referencedID , MessageLevel.ERROR); string referencedTypeWithoutPrefix = StringManipulationManager.ExtractAllAfterSeparator(refType, StringManipulationManager.SeparatorDot); } } else { OnMessage("Referenced object on property: " + prop.DeclaringType + "." + prop.Name + ", elements ID:" + element.ID + " not in model. Referenced: " + refType + ", ID:" + referencedID , MessageLevel.WARNING); string referencedTypeWithoutPrefix = StringManipulationManager.ExtractAllAfterSeparator(refType, StringManipulationManager.SeparatorDot); } } }
private void SetReferenceToProperty(CIMObject element, object something, string attValue, PropertyInfo prop, ConcreteModel model) { if (!string.IsNullOrEmpty(attValue)) { Type referencedType = prop.PropertyType; string referencedID = StringManipulationManager.ExtractAllAfterSeparator(attValue, StringManipulationManager.SeparatorSharp); object referencedObject = model.GetObjectByID(referencedID); if (referencedObject == null) { if (!(referencedType.GetProperty("Value") != null && referencedType.GetProperty("Multiplier") != null && referencedType.GetProperty("Unit") != null) && referencedType.Name != "AbsoluteDate") { OnMessage("Referenced object on property: " + prop.DeclaringType + "." + prop.Name + ", elements ID:" + element.ID + " not in model. Referenced: " + referencedType.ToString() + ", ID:" + referencedID , MessageLevel.WARNING); string propertyType = StringManipulationManager.ExtractAllAfterSeparator(referencedType.FullName, StringManipulationManager.SeparatorDot); } ////otherwise its DataType and its already set } else { if (referencedObject.GetType().Equals(referencedType) || referencedObject.GetType().IsSubclassOf(referencedType)) { prop.SetValue(something, referencedObject, null); } else { string referencedObjectType = StringManipulationManager.ExtractAllAfterSeparator(referencedObject.GetType().FullName, StringManipulationManager.SeparatorDot); string propertyType = StringManipulationManager.ExtractAllAfterSeparator(referencedType.FullName, StringManipulationManager.SeparatorDot); } } } }
/// <summary> /// Method instantiates all classes from <c>CIM_Model</c> using class definitions from <c>assembly</c> /// All instances will have ID, and properties, that are not references, set and will be stored in model /// </summary> /// <param name="CIM_Model">model representing cim/xml</param> /// <param name="assembly">assembly that contains classes used in model</param> private void InstantiateClassesWithSimpleValues(CIMModel CIM_Model, Assembly assembly, ref ConcreteModel concreteModel) { ////FOREACH TYPE IN MODEL foreach (string type in CIM_Model.ModelMap.Keys) { SortedDictionary <string, CIMObject> objects = CIM_Model.ModelMap[type]; ////FOREACH OBJECT WITH ID THAT BELONGS TO TYPE foreach (string objID in objects.Keys) { ////GET THE OBJECT CIMObject element = objects[objID]; Type classType; ////AQUIRE TYPE FROM ASSEMBLY classType = assembly.GetType(ActiveNamespace + "." + type); if (classType == null) { OnMessage("Class for element (" + element.ID + ") not found in assembly:" + ActiveNamespace + "." + type + " - validation of document failed!" , MessageLevel.ERROR); continue; } ////WITH TYPE MAKE AN INSTANCE object instance = Activator.CreateInstance(classType); ////AND SET ID TO THAT INSTANCE PropertyInfo propID = classType.GetProperty("ID"); propID.SetValue(instance, objID, null); ////SET SIMPLE VALUE ATTRIBUTES ProcessAttributes(assembly, element, classType, instance); ////SAVE OBJECT IN MODEL string insertEl = concreteModel.InsertObjectInModelMap(instance, classType); if (!string.IsNullOrEmpty(insertEl)) { OnMessage(string.Format("Inserting in model error on element ID {0} . Message: {1}", objID, insertEl), MessageLevel.WARNING); } } } }
/// <summary> /// Creates ConcreteModel from CIMModel using classes from assembly /// </summary> /// <param name="CIM_Model">model of cim/xml that is used to create ConcreteModel</param> /// <param name="assembly">contains classes for model</param> public ConcreteModelBuildingResult GenerateModel(CIMModel CIM_Model, Assembly assembly, string type, ref ConcreteModel model) { //model = new ConcreteModel(); result = new ConcreteModelBuildingResult(); activeNamespace = type; if (CIM_Model != null && assembly != null) { try { //two iterations //- first - only simple value/enumerations and instantiate the class //- second - create connections InstantiateClassesWithSimpleValues(CIM_Model, assembly, ref model); //second iteration for setting up references (excluding dataTypes)GOES HERE ConnectModelElements(CIM_Model, assembly, ref model); result.MissingValues = GenerateMissingMandatoryValuesReport(model, assembly); } catch (Exception ex) { OnMessage(ex.Message, MessageLevel.ERROR); } } else { OnMessage("Model or assembly are not selected.", MessageLevel.ERROR); } return(result); }
private void ConnectModelElements(CIMModel CIM_Model, Assembly assembly, ref ConcreteModel concreteModel) { foreach (string type in CIM_Model.ModelMap.Keys) { SortedDictionary <string, CIMObject> objects = CIM_Model.ModelMap[type]; foreach (string objID in objects.Keys) { CIMObject element = objects[objID]; Type classType; classType = assembly.GetType(ActiveNamespace + "." + type); if (classType == null) { OnMessage("Element (" + element.ID + ") not found in assembly:" + ActiveNamespace + "." + type + " - validation of document failed!", MessageLevel.ERROR); continue; } ////aquire object from concrete model object currentObject = concreteModel.GetObjectByTypeAndID(classType, objID); if (currentObject != null) { foreach (int attKey in element.MyAttributes.Keys) { string propertyName = StringManipulationManager.ExtractShortestName(CIM_Model.ModelContext.ReadAttributeWithCode(attKey), StringManipulationManager.SeparatorDot); propertyName = StringManipulationManager.CreateHungarianNotation(propertyName); if (propertyName.Equals(type)) { propertyName = propertyName + "P"; } PropertyInfo prop = classType.GetProperty(propertyName); if (prop == null) { OnMessage("Property " + propertyName + " not found in class " + element.CIMType + ", elements ID:" + element.ID + " - validation of document failed!", MessageLevel.ERROR); continue; } ////if it is a list or collection of references if (prop.PropertyType.IsGenericType) { Type propertyListType = prop.PropertyType.GetGenericArguments()[0]; List <ObjectAttribute> attList = element.MyAttributes[attKey]; ////get the property as IList IList list = (IList)prop.GetValue(currentObject, null); foreach (ObjectAttribute att in attList) { ////this part should add a reference to IList if (!IsSimpleValue(propertyListType) && !propertyListType.IsEnum) { AddReferenceToList(element, ref list, att.Value, prop, concreteModel); } } } else { List <ObjectAttribute> attList = element.MyAttributes[attKey]; ////if its not a list... ObjectAttribute att = attList.ElementAt(0); if (null != prop && prop.CanWrite) { if (!IsSimpleValue(prop.PropertyType) && !prop.PropertyType.IsEnum) { SetReferenceToProperty(element, currentObject, att.Value, prop, concreteModel); } } } } ////embeded elements - lists if (element.GetEmbeddedChildren() != null) { foreach (string attKey in element.GetEmbeddedChildren().Keys) { ////first is the name of property string propertyName = StringManipulationManager.ExtractShortestName(attKey, StringManipulationManager.SeparatorDot); propertyName = StringManipulationManager.CreateHungarianNotation(propertyName); if (propertyName.Equals(type)) { propertyName = propertyName + "P"; } PropertyInfo prop = classType.GetProperty(propertyName); if (prop != null && prop.PropertyType.IsGenericType) { Type propertyListType = prop.PropertyType.GetGenericArguments()[0]; List <string> attList = element.GetEmbeddedChildren()[attKey]; ////get the property as IList IList list = (IList)prop.GetValue(currentObject, null); foreach (string att in attList) { ////this part should add a reference to IList if (!IsSimpleValue(propertyListType) && !propertyListType.IsEnum) { AddReferenceToList(element, ref list, att, prop, concreteModel); } } } else { List <string> attList = element.GetEmbeddedChildren()[attKey]; ////if its not a list... string att = attList.ElementAt(0); if (prop != null && prop.CanWrite) { if (!IsSimpleValue(prop.PropertyType) && !prop.PropertyType.IsEnum) { SetReferenceToProperty(element, currentObject, att, prop, concreteModel); } } } } } } else { OnMessage("Object of class:" + classType + ", with ID:" + objID + " not found in model! Unable to create concrete model." , MessageLevel.ERROR); } } } }