private void CompileConcept(DocTemplateUsage concept, DocModelView view, TypeBuilder tb) { bool includeconcept = true; if (this.m_exchange != null) { includeconcept = false; foreach (DocExchangeItem ei in concept.Exchanges) { if (ei.Exchange == this.m_exchange && ei.Applicability == DocExchangeApplicabilityEnum.Export && (ei.Requirement == DocExchangeRequirementEnum.Mandatory || ei.Requirement == DocExchangeRequirementEnum.Optional)) { includeconcept = true; } } } // bool ConceptTemplateA([Parameter1, ...]); // { // // for loading reference value: // .ldfld [AttributeRule] // .ldelem [Index] // for collection, get element by index // .castclass [EntityRule] for entity, cast to expected type; // // for object graphs, repeat the above instructions to load value // // for loading constant: // .ldstr 'value' // // for comparison functions: // .cge // // for logical aggregations, repeat each item, pushing 2 elements on stack, then run comparison // .or // // return the boolean value on the stack // .ret; // } // bool[] ConceptA() // { // bool[] result = new bool[2]; // // if parameters are specified, call for each template rule; otherwise call just once // result[0] = ConceptTemplateA([Parameter1, ...]); // TemplateRule#1 // result[1] = ConceptTemplateA([Parameter1, ...]); // TemplateRule#2 // // return result; // } // compile a method for the template definition, where parameters are passed to the template #if true if (includeconcept && concept.Definition != null) { MethodInfo methodTemplate = this.RegisterTemplate(concept.Definition); // verify that definition is compatible with entity (user error) if (methodTemplate != null && methodTemplate.DeclaringType.IsAssignableFrom(tb)) { string methodname = DocumentationISO.MakeLinkName(view) + "_" + DocumentationISO.MakeLinkName(concept.Definition); MethodBuilder method = tb.DefineMethod(methodname, MethodAttributes.Public, CallingConventions.HasThis, typeof(bool[]), null); ILGenerator generator = method.GetILGenerator(); DocModelRule[] parameters = concept.Definition.GetParameterRules(); if (parameters != null && parameters.Length > 0) { // allocate array of booleans, store as local variable generator.DeclareLocal(typeof(bool[])); generator.Emit(OpCodes.Ldc_I4, concept.Items.Count); generator.Emit(OpCodes.Newarr, typeof(bool)); generator.Emit(OpCodes.Stloc_0); // call for each item with specific parameters for (int row = 0; row < concept.Items.Count; row++) { DocTemplateItem docItem = concept.Items[row]; generator.Emit(OpCodes.Ldloc_0); // push the array object onto the stack, for storage later generator.Emit(OpCodes.Ldc_I4, row); // push the array index onto the stack for storage later generator.Emit(OpCodes.Ldarg_0); // push the *this* pointer for the IFC object instance // push parameters onto stack for (int col = 0; col < parameters.Length; col++) { DocModelRule docParam = parameters[col]; string paramvalue = docItem.GetParameterValue(docParam.Identification); if (paramvalue != null) { DocDefinition docParamType = concept.Definition.GetParameterType(docParam.Identification, this.m_definitions); if (docParamType is DocDefined) { DocDefined docDefined = (DocDefined)docParamType; switch (docDefined.DefinedType) { case "INTEGER": { Int64 ival = 0; Int64.TryParse(paramvalue, out ival); generator.Emit(OpCodes.Ldc_I8, ival); generator.Emit(OpCodes.Box); } break; case "REAL": { Double dval = 0.0; Double.TryParse(paramvalue, out dval); generator.Emit(OpCodes.Ldc_R8, dval); generator.Emit(OpCodes.Box); } break; case "STRING": generator.Emit(OpCodes.Ldstr, paramvalue); break; default: generator.Emit(OpCodes.Ldstr, paramvalue); break; } } else { // assume string generator.Emit(OpCodes.Ldstr, paramvalue); } } else { generator.Emit(OpCodes.Ldnull); } } generator.Emit(OpCodes.Call, methodTemplate); // call the validation function for the concept template generator.Emit(OpCodes.Stelem_I1); // store the result (bool) into an array slot } // return the array of boolean results generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ret); } else { // allocate array of booleans, store as local variable generator.DeclareLocal(typeof(bool[])); generator.Emit(OpCodes.Ldc_I4, 1); generator.Emit(OpCodes.Newarr, typeof(bool)); generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Ldloc_0); // push the array object onto the stack, for storage later generator.Emit(OpCodes.Ldc_I4, 0); // push the array index onto the stack for storage later // call once generator.Emit(OpCodes.Ldarg_0); // push the *this* pointer for the IFC object instance generator.Emit(OpCodes.Call, methodTemplate); // call the validation function for the concept template generator.Emit(OpCodes.Stelem_I1); // store the result (bool) into an array slot // return the array of boolean results generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ret); } } else { System.Diagnostics.Debug.WriteLine("Incompatible template: " + tb.Name + " - " + concept.Definition.Name); } } #endif // recurse foreach (DocTemplateUsage docChild in concept.Concepts) { CompileConcept(docChild, view, tb); } }
public string FormatData(DocProject docProject, DocPublication docPublication, DocExchangeDefinition docExchange, Dictionary <string, DocObject> map, Dictionary <long, SEntity> instances, SEntity root, bool markup) { //Guid guidMapping = Guid.Parse("");//... StringBuilder sb = new StringBuilder(); foreach (DocModelView docView in docPublication.Views) { foreach (DocConceptRoot docRoot in docView.ConceptRoots) { // look for specific concept root dealing with mappings foreach (DocTemplateUsage docConcept in docRoot.Concepts) { if (docConcept.Definition != null && docConcept.Definition.Name.Equals("External Data Constraints") && docConcept.Items.Count > 0)//... { bool included = true; if (docExchange != null) { included = false; // if exhcnage specified, check for inclusion foreach (DocExchangeItem docExchangeItem in docConcept.Exchanges) { if (docExchangeItem.Exchange == docExchange && docExchangeItem.Requirement == DocExchangeRequirementEnum.Mandatory) { included = true; break; } } } // check if there are any instances to populate table if (included) { included = false; foreach (SEntity e in instances.Values) { string eachname = e.GetType().Name; if (docRoot.ApplicableEntity.IsInstanceOfType(e)) { included = true; break; } } } if (included) { string table = docConcept.Items[0].GetParameterValue("Table"); string query = docConcept.Items[0].GetParameterValue("Reference"); sb.AppendLine("<h4>" + docConcept.Name + "</h4>"); sb.AppendLine("<table class=\"gridtable\">"); List <string> colstyles = new List <string>(); List <string> colformat = new List <string>(); List <CvtValuePath> colmaps = new List <CvtValuePath>(); // generate header row sb.AppendLine("<tr>"); foreach (DocTemplateItem docItem in docConcept.Items) { string name = docItem.GetParameterValue("Name"); string disp = "#" + docItem.GetColor().ToArgb().ToString("X8"); //docItem.GetParameterValue("Color");docItem.GetParameterValue("Color"); string expr = docItem.GetParameterValue("Reference"); string form = docItem.GetParameterValue("Format"); string style = ""; if (!String.IsNullOrEmpty(disp)) { style = " style=\"background-color:" + disp + ";\""; } colstyles.Add(style); string format = ""; if (!String.IsNullOrEmpty(form)) { format = form; } colformat.Add(format); string desc = ""; CvtValuePath valpath = CvtValuePath.Parse(expr, map); //todo: move out of loop colmaps.Add(valpath); if (valpath != null) { desc = /*valpath.GetDescription(map) + " " + */ valpath.ToString().Replace("\\", " "); } sb.Append("<th><a href=\"../../schema/views/" + DocumentationISO.MakeLinkName(docView) + "/" + DocumentationISO.MakeLinkName(docExchange) + ".htm#" + DocumentationISO.MakeLinkName(docConcept) + "\" title=\"" + desc + "\">"); sb.Append(name); sb.Append("</a></th>"); } ; sb.AppendLine("</tr>"); // generate data rows foreach (SEntity e in instances.Values) { string eachname = e.GetType().Name; if (docRoot.ApplicableEntity.IsInstanceOfType(e)) { bool includerow = true; StringBuilder sbRow = new StringBuilder(); sbRow.Append("<tr>"); int iCol = 0; foreach (DocTemplateItem docItem in docConcept.Items) { sbRow.Append("<td" + colstyles[iCol]); CvtValuePath valpath = colmaps[iCol]; string format = colformat[iCol]; iCol++; if (valpath != null) { string nn = docItem.GetParameterValue("Name"); object value = valpath.GetValue(e, null); if (value == e) { value = e.GetType().Name; } else if (value is SEntity) { // use name FieldInfo fieldValue = value.GetType().GetField("Name"); if (fieldValue != null) { value = fieldValue.GetValue(value); } } else if (value is System.Collections.IList) { System.Collections.IList list = (System.Collections.IList)value; StringBuilder sbList = new StringBuilder(); foreach (object elem in list) { FieldInfo fieldName = elem.GetType().GetField("Name"); if (fieldName != null) { object elemname = fieldName.GetValue(elem); if (elemname != null) { FieldInfo fieldValue = elemname.GetType().GetField("Value"); if (fieldValue != null) { object elemval = fieldValue.GetValue(elemname); sbList.Append(elemval.ToString()); } } } sbList.Append("; <br/>"); } value = sbList.ToString(); } else if (value is Type) { value = ((Type)value).Name; } if (!String.IsNullOrEmpty(format)) { if (format.Equals("Required") && value == null) { includerow = false; } } if (value != null) { FieldInfo fieldValue = value.GetType().GetField("Value"); if (fieldValue != null) { value = fieldValue.GetValue(value); } if (format != null && format.Equals("True") && (value == null || !value.ToString().Equals("True"))) { includerow = false; } if (value is Double) { sbRow.Append(" align=\"right\">"); sbRow.Append(((Double)value).ToString("N3")); } else if (value is List <Int64> ) { sbRow.Append(">"); // latitude or longitude List <Int64> intlist = (List <Int64>)value; if (intlist.Count >= 3) { sbRow.Append(intlist[0] + "° " + intlist[1] + "' " + intlist[2] + "\""); } } else if (value != null) { sbRow.Append(">"); sbRow.Append(value.ToString()); // todo: html-encode } } else { sbRow.Append(">"); sbRow.Append(" "); } } else { sbRow.Append(">"); } sbRow.Append("</td>"); } sbRow.AppendLine("</tr>"); if (includerow) { sb.Append(sbRow.ToString()); } } } sb.AppendLine("</table>"); sb.AppendLine("<br/>"); } } } } } return(sb.ToString()); }
/// <summary> /// Saves all content to folder hierarchy /// </summary> /// <param name="project"></param> /// <param name="path"></param> public static void Save(DocProject project, string path, Dictionary <string, DocObject> mapEntity, FolderStorageOptions options) { bool bExportSchema = ((options & FolderStorageOptions.Schemas) != 0); bool bExportExchanges = ((options & FolderStorageOptions.Exchanges) != 0); bool bExportExamples = ((options & FolderStorageOptions.Examples) != 0); bool bExportLocalize = ((options & FolderStorageOptions.Localization) != 0); Compiler compiler = new Compiler(project, null, null, false); System.Reflection.Emit.AssemblyBuilder assembly = compiler.Assembly; // -exchanges (or mvd?) // {exchange}.mvdxml - definition // {exchange}.cs - C# partial classes for capturing exchange --- later // templates.mvdxml - shared templates // -figures -- manually added // -formats // -json // -step // -ttl // -xml // -samples // {sample}.ifcxml - ifcxml is native format for easier browsing, comparing, and validating // {sample}.htm - documentation for example // {sample}.png - preview image of example // {sample} - subdirectory if children // -schemas // {version} // {schema} // {class}.cs - definition in C# // {class}.htm - documentation in HTML // schema.cs - functions and // schema.htm - documentation of schema in HTML // schema.svg - diagram of schema in SVG // templates.ifcxml - property and quantity templates // localization // {locale}.txt - localized definitions // ifc.csproj if (bExportSchema) { string pathClasses = path + @"\schemas\" + project.GetSchemaIdentifier(); System.IO.Directory.CreateDirectory(pathClasses); FormatCSC.GenerateCode(project, pathClasses, mapEntity, DocCodeEnum.All); // generate ifcxml for templates DocumentationISO.DoExport(project, null, pathClasses + @"\templates.ifcxml", null, null, DocDefinitionScopeEnum.Default, null, mapEntity); // XSD configuration // not needed -- can re-read from C# classes //DocumentationISO.DoExport(project, null, pathClasses + @"\xsdconfig.xml", null, null, DocDefinitionScopeEnum.Default, null, mapEntity); } if (bExportExchanges) { string pathExchanges = path + @"\exchanges"; System.IO.Directory.CreateDirectory(pathExchanges); foreach (DocModelView docView in project.ModelViews) { string pathView = pathExchanges + @"\" + DocumentationISO.MakeLinkName(docView); DocumentationISO.DoExport(project, null, pathView + ".mvdxml", new DocModelView[] { docView }, null, DocDefinitionScopeEnum.Default, null, mapEntity); //... future: once it works flawlessly...FormatCSC.GenerateExchange(project, docView, pathView, mapEntity); } } if (bExportExamples) { // compile schema into assembly Type typeProject = Compiler.CompileProject(project); string pathSamples = path + @"\examples"; string pathSamplesWeb = "examples"; System.IO.Directory.CreateDirectory(pathSamples); using (StreamWriter writerIndex = new StreamWriter(Stream.Null)) //...pathSamples + @"\index.htm")) { writerIndex.WriteLine("<html><body>"); writerIndex.WriteLine("<table>"); foreach (DocExample docExam in project.Examples) { // generate ifcxml for each sample ExportExample(pathSamples, pathSamplesWeb, typeProject, docExam, writerIndex); } writerIndex.WriteLine("</table>"); writerIndex.WriteLine("</body></html>"); } } // terms, abbreviations, references, bibliography, ... #if false string pathTerms = path + @"\terms"; System.IO.Directory.CreateDirectory(pathSamples); foreach (DocTerm docTerm in this.m_project.Terms) { } #endif // localization SortedList <string, string> listLocale = new SortedList <string, string>(); foreach (DocObject eachobj in mapEntity.Values) { if (eachobj.Localization != null) { foreach (DocLocalization doclocal in eachobj.Localization) { // only deal with languages, not regions if (doclocal.Locale != null && doclocal.Locale.Length >= 2) { string language = doclocal.Locale.Substring(0, 2); if (!listLocale.ContainsKey(language)) { listLocale.Add(language, doclocal.Locale); } } } } } if (bExportLocalize) { string pathLocalize = path + @"\localize"; System.IO.Directory.CreateDirectory(pathLocalize); foreach (string locale in listLocale.Keys) { string pathLocale = path + @"\localize\" + locale + ".txt"; using (FormatCSV format = new FormatCSV(pathLocale)) { format.Instance = project; format.Locales = new string[] { locale }; format.Scope = DocDefinitionScopeEnum.Default; format.Save(); } } } }
/// <summary> /// /// </summary> /// <param name="path">Path of parent</param> /// <param name="docExample"></param> private static void ExportExample(string path, string webpath, Type typeProject, DocExample docExample, StreamWriter writerIndex) { string pathExample = path + @"\" + DocumentationISO.MakeLinkName(docExample); string pathExampleWeb = webpath + "/" + DocumentationISO.MakeLinkName(docExample); // load SPF from internal content if (docExample.File != null) { try { using (MemoryStream streamSource = new MemoryStream(docExample.File)) { StepSerializer serSource = new StepSerializer(typeProject); object project = serSource.ReadObject(streamSource); // write original IFC file as-is (including comments) -- or could be normalized using StepSerializer using (FileStream streamIFC = new FileStream(pathExample + ".ifc", FileMode.Create)) { streamIFC.Write(docExample.File, 0, docExample.File.Length); } #if false using (FileStream streamXML = new FileStream(pathExample + ".ifcxml", FileMode.Create)) { BuildingSmart.Serialization.Xml.XmlSerializer streamTarget = new BuildingSmart.Serialization.Xml.XmlSerializer(typeProject); streamTarget.WriteObject(streamXML, project); } using (FileStream streamJSN = new FileStream(pathExample + ".json", FileMode.Create)) { BuildingSmart.Serialization.Json.JsonSerializer streamTarget = new BuildingSmart.Serialization.Json.JsonSerializer(typeProject); streamTarget.WriteObject(streamJSN, project); } using (FileStream streamTTL = new FileStream(pathExample + ".ttl", FileMode.Create)) { BuildingSmart.Serialization.Turtle.TurtleSerializer streamTarget = new BuildingSmart.Serialization.Turtle.TurtleSerializer(typeProject); streamTarget.WriteObject(streamTTL, project); } #endif } } catch (Exception xx) { System.Diagnostics.Debug.WriteLine(xx.Message); return; } writerIndex.WriteLine("<tr><td><a href=\"./" + webpath + ".htm\">" + docExample.Name + "</a></td>"); WriteExampleIndexFormat(writerIndex, pathExampleWeb, "ifc"); WriteExampleIndexFormat(writerIndex, pathExampleWeb, "ifcxml"); WriteExampleIndexFormat(writerIndex, pathExampleWeb, "json"); WriteExampleIndexFormat(writerIndex, pathExampleWeb, "ttl"); // github link writerIndex.WriteLine("<td><a href=\"https://github.com/BuildingSMART/IfcDoc/blob/master/IfcKit/" + pathExampleWeb + ".ifc\"><img src=\"github.png\" width=\"32\" height=\"32\" /></a></td>"); writerIndex.WriteLine("</tr>"); } else { // write header row writerIndex.WriteLine("<tr><th colspan=\"6\"><a href=\"./" + pathExampleWeb + ".htm\">" + docExample.Name + "</a></th></tr>"); } if (!String.IsNullOrEmpty(docExample.Documentation)) { string filehtml = pathExample + ".htm"; using (StreamWriter writerHtml = new StreamWriter(filehtml, false, Encoding.UTF8)) { writerHtml.Write(docExample.Documentation); } } if (docExample.Examples.Count > 0) { System.IO.Directory.CreateDirectory(pathExample); // recurse foreach (DocExample docSub in docExample.Examples) { ExportExample(pathExample, pathExampleWeb, typeProject, docSub, writerIndex); } } }
public string FormatDataConcept(DocProject docProject, DocPublication docPublication, DocExchangeDefinition docExchange, Dictionary <string, DocObject> map, Dictionary <string, Type> typemap, Dictionary <long, SEntity> instances, SEntity root, bool markup, DocModelView docView, DocConceptRoot docRoot, DocTemplateUsage docConcept) { StringBuilder sb = new StringBuilder(); string table = docConcept.Items[0].GetParameterValue("Table"); string query = docConcept.Items[0].GetParameterValue("Reference"); sb.AppendLine("<h4>" + docConcept.Name + "</h4>"); sb.AppendLine("<table class=\"gridtable\">"); List <string> colstyles = new List <string>(); List <string> colformat = new List <string>(); List <CvtValuePath> colmaps = new List <CvtValuePath>(); // generate header row sb.AppendLine("<tr>"); foreach (DocTemplateItem docItem in docConcept.Items) { string name = docItem.GetParameterValue("Name"); string disp = "#" + docItem.GetColor().ToArgb().ToString("X8"); //docItem.GetParameterValue("Color");docItem.GetParameterValue("Color"); string expr = docItem.GetParameterValue("Reference"); string form = docItem.GetParameterValue("Format"); string style = ""; if (!String.IsNullOrEmpty(disp)) { style = " style=\"background-color:" + disp + ";\""; } colstyles.Add(style); string format = ""; if (!String.IsNullOrEmpty(form)) { format = form; } colformat.Add(format); string desc = ""; CvtValuePath valpath = CvtValuePath.Parse(expr, map); colmaps.Add(valpath); if (valpath != null) { desc = /*valpath.GetDescription(map) + " " + */ valpath.ToString().Replace("\\", " "); } sb.Append("<th><a href=\"../../schema/views/" + DocumentationISO.MakeLinkName(docView) + "/" + DocumentationISO.MakeLinkName(docExchange) + ".htm#" + DocumentationISO.MakeLinkName(docConcept) + "\" title=\"" + desc + "\">"); sb.Append(name); sb.Append("</a></th>"); } ; sb.AppendLine("</tr>"); // generate data rows List <DocModelRule> trace = new List <DocModelRule>(); foreach (SEntity e in instances.Values) { string eachname = e.GetType().Name; if (docRoot.ApplicableEntity.IsInstanceOfType(e)) { bool includerow = true; // if root has more complex rules, check them if (docRoot.ApplicableTemplate != null && docRoot.ApplicableItems.Count > 0) { includerow = false; // must check1 foreach (DocTemplateItem docItem in docRoot.ApplicableItems) { foreach (DocModelRule rule in docRoot.ApplicableTemplate.Rules) { try { trace.Clear(); bool?result = rule.Validate(e, docItem, typemap, trace, e, null, null); if (result == true && docRoot.ApplicableOperator == DocTemplateOperator.Or) { includerow = true; break; } } catch { docRoot.ToString(); } } // don't yet support AND or other operators if (includerow) { break; } } } if (includerow) { StringBuilder sbRow = new StringBuilder(); sbRow.Append("<tr>"); int iCol = 0; foreach (DocTemplateItem docItem in docConcept.Items) { sbRow.Append("<td" + colstyles[iCol]); CvtValuePath valpath = colmaps[iCol]; string format = colformat[iCol]; iCol++; if (valpath != null) { string nn = docItem.GetParameterValue("Name"); object value = valpath.GetValue(e, null); if (value == e) { value = e.GetType().Name; } else if (value is SEntity) { // use name FieldInfo fieldValue = value.GetType().GetField("Name"); if (fieldValue != null) { value = fieldValue.GetValue(value); } } else if (value is System.Collections.IList) { System.Collections.IList list = (System.Collections.IList)value; StringBuilder sbList = new StringBuilder(); foreach (object elem in list) { FieldInfo fieldName = elem.GetType().GetField("Name"); if (fieldName != null) { object elemname = fieldName.GetValue(elem); if (elemname != null) { FieldInfo fieldValue = elemname.GetType().GetField("Value"); if (fieldValue != null) { object elemval = fieldValue.GetValue(elemname); sbList.Append(elemval.ToString()); } } } sbList.Append("; <br/>"); } value = sbList.ToString(); } else if (value is Type) { value = ((Type)value).Name; } if (!String.IsNullOrEmpty(format)) { if (format.Equals("Required") && value == null) { includerow = false; } } if (value != null) { FieldInfo fieldValue = value.GetType().GetField("Value"); if (fieldValue != null) { value = fieldValue.GetValue(value); } if (format != null && format.Equals("True") && (value == null || !value.ToString().Equals("True"))) { includerow = false; } if (value is Double) { sbRow.Append(" align=\"right\">"); sbRow.Append(((Double)value).ToString("N3")); } else if (value is List <Int64> ) { sbRow.Append(">"); // latitude or longitude List <Int64> intlist = (List <Int64>)value; if (intlist.Count >= 3) { sbRow.Append(intlist[0] + "° " + intlist[1] + "' " + intlist[2] + "\""); } } else if (value != null) { sbRow.Append(">"); sbRow.Append(value.ToString()); // todo: html-encode } } else { sbRow.Append(">"); sbRow.Append(" "); } } else { sbRow.Append(">"); } sbRow.Append("</td>"); } sbRow.AppendLine("</tr>"); if (includerow) { sb.Append(sbRow.ToString()); } } } } sb.AppendLine("</table>"); sb.AppendLine("<br/>"); return(sb.ToString()); }