Example #1
0
        public Compiler(DocProject project, DocModelView[] views, DocExchangeDefinition exchange, bool psets)
        {
            this.m_project  = project;
            this.m_views    = views;
            this.m_exchange = exchange;
            this.m_psets    = psets;

            // version needs to be included for extracting XML namespace (Major.Minor.Addendum.Corrigendum)
            string                 version            = project.GetSchemaVersion();
            ConstructorInfo        conContract        = (typeof(AssemblyVersionAttribute).GetConstructor(new Type[] { typeof(string) }));
            CustomAttributeBuilder cabAssemblyVersion = new CustomAttributeBuilder(conContract, new object[] { version });

            string schemaid = project.GetSchemaIdentifier();
            string assembly = "buildingSmart." + schemaid;
            string module   = assembly + ".dll";

            this.m_rootnamespace = assembly + ".";

            this.m_assembly    = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(assembly), AssemblyBuilderAccess.RunAndSave, new CustomAttributeBuilder[] { cabAssemblyVersion });
            this.m_module      = this.m_assembly.DefineDynamicModule(module, module);
            this.m_definitions = new Dictionary <string, DocObject>();
            this.m_types       = new Dictionary <string, Type>();
            this.m_fields      = new Dictionary <Type, Dictionary <string, FieldInfo> >();
            this.m_templates   = new Dictionary <DocTemplateDefinition, MethodInfo>();
            this.m_namespaces  = new Dictionary <string, string>();

            Dictionary <DocObject, bool> included = null;

            if (this.m_views != null)
            {
                included = new Dictionary <DocObject, bool>();
                foreach (DocModelView docView in this.m_views)
                {
                    this.m_project.RegisterObjectsInScope(docView, included);
                }
            }
            if (psets)
            {
                foreach (DocPropertyEnumeration docPropEnum in project.PropertyEnumerations)
                {
                    DocEnumeration docType = docPropEnum.ToEnumeration();
                    if (!this.m_definitions.ContainsKey(docType.Name))
                    {
                        this.m_definitions.Add(docType.Name, docType);
                    }
                }
            }

            foreach (DocSection docSection in project.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocEntity docEntity in docSchema.Entities)
                    {
                        if (included == null || included.ContainsKey(docEntity))
                        {
                            if (!this.m_definitions.ContainsKey(docEntity.Name))
                            {
                                this.m_definitions.Add(docEntity.Name, docEntity);
                                this.m_namespaces.Add(docEntity.Name, docSchema.Name);
                            }
                        }
                    }

                    foreach (DocType docType in docSchema.Types)
                    {
                        if (included == null || included.ContainsKey(docType))
                        {
                            if (!this.m_definitions.ContainsKey(docType.Name))
                            {
                                this.m_definitions.Add(docType.Name, docType);
                                this.m_namespaces.Add(docType.Name, docSchema.Name);
                            }
                        }
                    }
                }
            }

            // second pass:
            if (psets)
            {
                foreach (DocSection docSection in project.Sections)
                {
                    foreach (DocSchema docSchema in docSection.Schemas)
                    {
                        foreach (DocPropertySet docPset in docSchema.PropertySets)
                        {
                            DocEntity docType = docPset.ToEntity(this.m_definitions);
                            if (!this.m_definitions.ContainsKey(docType.Name))
                            {
                                this.m_definitions.Add(docType.Name, docType);
                                this.m_namespaces.Add(docType.Name, docSchema.Name);
                            }
                        }

                        foreach (DocQuantitySet docQset in docSchema.QuantitySets)
                        {
                            DocEntity docType = docQset.ToEntity(this.m_definitions);
                            if (!this.m_definitions.ContainsKey(docType.Name))
                            {
                                this.m_definitions.Add(docType.Name, docType);
                                this.m_namespaces.Add(docType.Name, docSchema.Name);
                            }
                        }
                    }
                }
            }

            // first register types and fields
            foreach (string key in this.m_definitions.Keys)
            {
                Type typereg = RegisterType(key);

                // localization -- use custom attributes for now -- ideal way would be to use assembly resources, though has bugs in .net 4.0
                if (typereg is TypeBuilder)
                {
                    TypeBuilder tb = (TypeBuilder)typereg;

                    DocObject docObj = this.m_definitions[key];
                    foreach (DocLocalization docLocal in docObj.Localization)
                    {
                        CustomAttributeBuilder cab = docLocal.ToCustomAttributeBuilder();
                        if (cab != null)
                        {
                            tb.SetCustomAttribute(cab);
                        }
                    }
                }
            }

            // now register template functions (may depend on fields existing)

            // find associated ConceptRoot for model view, define validation function
            if (this.m_views != null)
            {
                foreach (DocModelView view in this.m_views)
                {
                    string viewname = view.Code;
                    foreach (DocConceptRoot root in view.ConceptRoots)
                    {
                        Type tOpen = null;

                        if (this.m_types.TryGetValue(root.ApplicableEntity.Name, out tOpen) && tOpen is TypeBuilder)
                        {
                            TypeBuilder tb = (TypeBuilder)tOpen;


                            // new: generate type for concept root
                            //if (view.Name != null && root.Name != null)
                            {
                                /*
                                 * string typename = this.m_rootnamespace + "." + view.Name.Replace(" ", "_") + "." + root.Name.Replace(" ", "_");
                                 * //Type tbConceptRoot = RegisterType(typename);
                                 * TypeBuilder tbRoot = this.m_module.DefineType(typename, attr, typebase);
                                 */

                                // add typebuilder to map temporarily in case referenced by an attribute within same class or base class
                                //this.m_types.Add(typename, tb);

                                foreach (DocTemplateUsage concept in root.Concepts)
                                {
                                    CompileConcept(concept, view, tb);
                                }
                            }
                        }
                    }
                }
            }

            //Dictionary<string, Stream> mapResStreams = new Dictionary<string, Stream>();
            //Dictionary<string, ResXResourceWriter> mapResources = new Dictionary<string, ResXResourceWriter>();

            // seal types once all are built
            List <TypeBuilder> listBase = new List <TypeBuilder>();

            foreach (string key in this.m_definitions.Keys)
            {
                Type tOpen = this.m_types[key];
                while (tOpen is TypeBuilder)
                {
                    listBase.Add((TypeBuilder)tOpen);
                    tOpen = tOpen.BaseType;
                }

                // seal in base class order
                for (int i = listBase.Count - 1; i >= 0; i--)
                {
                    Type tClosed = listBase[i].CreateType();
                    this.m_types[tClosed.Name] = tClosed;
                }
                listBase.Clear();


                // record bindings
                DocDefinition docDef = this.m_definitions[key] as DocDefinition;
                if (docDef != null)
                {
                    docDef.RuntimeType = this.m_types[key];

                    if (docDef is DocEntity)
                    {
                        DocEntity docEnt = (DocEntity)docDef;
                        foreach (DocAttribute docAttr in docEnt.Attributes)
                        {
                            docAttr.RuntimeField = docDef.RuntimeType.GetProperty(docAttr.Name);
                        }
                    }

#if false // bug in .net framework 4.0+ -- can't read resources dynamically defined
                    // capture localization
                    foreach (DocLocalization docLocal in docDef.Localization)
                    {
                        if (!String.IsNullOrEmpty(docLocal.Locale))
                        {
                            string major = docLocal.Locale.Substring(0, 2).ToLower();

                            ResXResourceWriter reswriter = null;
                            if (!mapResources.TryGetValue(major, out reswriter))
                            {
                                MemoryStream stream = new MemoryStream();
                                mapResStreams.Add(major, stream);

                                reswriter = new ResXResourceWriter(stream);
                                mapResources.Add(major, reswriter);
                            }

                            ResXDataNode node = new ResXDataNode(docDef.Name, docLocal.Name);
                            node.Comment = docLocal.Documentation;
                            reswriter.AddResource(node);
                        }
                    }
#endif
                }
            }

#if false
            foreach (string locale in mapResStreams.Keys)
            {
                ResXResourceWriter writer = mapResources[locale];
                writer.Generate();
                Stream stream = mapResStreams[locale];
                stream.Seek(0, SeekOrigin.Begin);
                m_module.DefineManifestResource("Resources." + locale + ".resx", stream, ResourceAttributes.Public);
            }
#endif
        }
Example #2
0
        /// <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();
                    }
                }
            }
        }
Example #3
0
        public Compiler(DocProject project, DocModelView[] views, DocExchangeDefinition exchange)
        {
            this.m_project  = project;
            this.m_views    = views;
            this.m_exchange = exchange;

            string schemaid = project.GetSchemaIdentifier();

            this.m_assembly    = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(schemaid), AssemblyBuilderAccess.RunAndSave);
            this.m_module      = this.m_assembly.DefineDynamicModule("IFC4.dll", "IFC4.dll");
            this.m_definitions = new Dictionary <string, DocObject>();
            this.m_types       = new Dictionary <string, Type>();
            this.m_fields      = new Dictionary <Type, Dictionary <string, FieldInfo> >();
            this.m_templates   = new Dictionary <DocTemplateDefinition, MethodInfo>();
            this.m_namespaces  = new Dictionary <string, string>();

            Dictionary <DocObject, bool> included = null;

            if (this.m_views != null)
            {
                included = new Dictionary <DocObject, bool>();
                foreach (DocModelView docView in this.m_views)
                {
                    this.m_project.RegisterObjectsInScope(docView, included);
                }
            }

            foreach (DocSection docSection in project.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocEntity docEntity in docSchema.Entities)
                    {
                        if (included == null || included.ContainsKey(docEntity))
                        {
                            if (!this.m_definitions.ContainsKey(docEntity.Name))
                            {
                                this.m_definitions.Add(docEntity.Name, docEntity);
                                this.m_namespaces.Add(docEntity.Name, docSchema.Name);
                            }
                        }
                    }

                    foreach (DocType docType in docSchema.Types)
                    {
                        if (included == null || included.ContainsKey(docType))
                        {
                            if (!this.m_definitions.ContainsKey(docType.Name))
                            {
                                this.m_definitions.Add(docType.Name, docType);
                                this.m_namespaces.Add(docType.Name, docSchema.Name);
                            }
                        }
                    }
                }
            }

            // first register types and fields
            foreach (string key in this.m_definitions.Keys)
            {
                RegisterType(key);
            }

            // now register template functions (may depend on fields existing)

            // find associated ConceptRoot for model view, define validation function
            if (this.m_views != null)
            {
                foreach (DocModelView view in this.m_views)
                {
                    string viewname = view.Code;
                    foreach (DocConceptRoot root in view.ConceptRoots)
                    {
                        Type tOpen = null;

                        if (this.m_types.TryGetValue(root.ApplicableEntity.Name, out tOpen) && tOpen is TypeBuilder)
                        {
                            TypeBuilder tb = (TypeBuilder)tOpen;
                            foreach (DocTemplateUsage concept in root.Concepts)
                            {
                                CompileConcept(concept, view, tb);
                            }
                        }
                    }
                }
            }



            // seal types once all are built
            List <TypeBuilder> listBase = new List <TypeBuilder>();

            foreach (string key in this.m_definitions.Keys)
            {
                Type tOpen = this.m_types[key];
                while (tOpen is TypeBuilder)
                {
                    listBase.Add((TypeBuilder)tOpen);
                    tOpen = tOpen.BaseType;
                }

                // seal in base class order
                for (int i = listBase.Count - 1; i >= 0; i--)
                {
                    Type tClosed = listBase[i].CreateType();
                    this.m_types[tClosed.Name] = tClosed;
                }
                listBase.Clear();


                // record bindings
                DocDefinition docDef = this.m_definitions[key] as DocDefinition;
                if (docDef != null)
                {
                    docDef.RuntimeType = this.m_types[key];

                    if (docDef is DocEntity)
                    {
                        DocEntity docEnt = (DocEntity)docDef;
                        foreach (DocAttribute docAttr in docEnt.Attributes)
                        {
                            docAttr.RuntimeField = docDef.RuntimeType.GetField(docAttr.Name);
                        }
                    }
                }
            }
        }
Example #4
0
        public string FormatDefinitions(DocProject docProject, DocPublication docPublication, Dictionary <string, DocObject> map, Dictionary <DocObject, bool> included)
        {
            // clear containers
            listPropertiesOutput.Clear();
            addedIndividuals.Clear();
            attribInverses.Clear();
            subTypesOfEntity.Clear();

            StringBuilder sb = new StringBuilder();

            string ifcversion = docProject.GetSchemaIdentifier();

            //string ifcns = "http://www.buildingsmart-tech.org/ifcOWL/" + ifcversion;
            //string ifcns = "http://ifcowl.openbimstandards.org/" + ifcversion;
            string ifcns = "http://www.buildingsmart-tech.org/ifc/" + ifcversion;

            // namespace definitions
            sb.AppendLine("@prefix :      <" + ifcns + "#> .");
            sb.AppendLine("@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .");
            sb.AppendLine("@prefix dce:   <http://purl.org/dc/elements/1.1/> .");
            sb.AppendLine("@prefix owl:   <http://www.w3.org/2002/07/owl#> .");
            sb.AppendLine("@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .");
            sb.AppendLine("@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .");
            sb.AppendLine("@prefix vann:  <http://purl.org/vocab/vann/> .");
            sb.AppendLine("@prefix list:  <https://w3id.org/list#> .");
            sb.AppendLine("@prefix expr:  <https://w3id.org/express#> .");
            sb.AppendLine("@prefix ifc:   <" + ifcns + "#> .");
            sb.AppendLine("@prefix cc:    <http://creativecommons.org/ns#> .");
            sb.AppendLine("");

            // ontology definition
            sb.AppendLine("<" + ifcns + ">");
            sb.AppendLine("\ta                              owl:Ontology ;");
            sb.AppendLine("\trdfs:comment                   \"Ontology automatically generated from the EXPRESS schema using the IfcDoc functions developed by Pieter Pauwels ([email protected]) and Walter Terkaj ([email protected]) \" ;");
            sb.AppendLine("\tcc:license                     <http://creativecommons.org/licenses/by/3.0/> ;");
            sb.AppendLine("\tdce:contributor                \"Jakob Beetz ([email protected])\" , \"Maria Poveda Villalon ([email protected])\" ;"); // \"Aleksandra Sojic ([email protected])\" ,
            sb.AppendLine("\tdce:creator                    \"Pieter Pauwels ([email protected])\" , \"Walter Terkaj  ([email protected])\" ;");
            sb.AppendLine("\tdce:date                       \"2015/10/02\" ;");
            sb.AppendLine("\tdce:description                \"OWL ontology for the IFC conceptual data schema and exchange file format for Building Information Model (BIM) data\" ;");
            sb.AppendLine("\tdce:identifier                 \"" + ifcversion + "\" ;");
            sb.AppendLine("\tdce:language                   \"en\" ;");
            sb.AppendLine("\tdce:title                      \"" + ifcversion + "\" ;");
            sb.AppendLine("\tvann:preferredNamespacePrefix  \"ifc\" ;");
            sb.AppendLine("\tvann:preferredNamespaceUri     \"" + ifcns + "\" ;");
            sb.AppendLine("\towl:imports                    <https://w3id.org/express> .");
            sb.AppendLine();

            // check which Inverse Attributes must be discarded because of conflicts
            // get subtypes of an entity
            foreach (DocSection docSection in docProject.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocEntity docEntity in docSchema.Entities)
                    {
                        // get supertype/subtype
                        if (docEntity.BaseDefinition != null)
                        {
                            if (!subTypesOfEntity.ContainsKey(docEntity.BaseDefinition))
                            {
                                subTypesOfEntity.Add(docEntity.BaseDefinition, new HashSet <string>());
                            }
                            subTypesOfEntity[docEntity.BaseDefinition].Add(docEntity.Name);
                        }

                        // check attributes
                        foreach (DocAttribute docAttr in docEntity.Attributes)
                        {
                            if (docAttr.Inverse != null)
                            {
                                var key = new Tuple <string, string>(docAttr.Inverse, docAttr.DefinedType);
                                if (!attribInverses.ContainsKey(key))
                                {
                                    attribInverses.Add(key, 1);
                                }
                                else
                                {
                                    attribInverses[key] += 1;
                                }
                            }
                        }
                    }
                }
            }

            // generate definitions
            foreach (DocSection docSection in docProject.Sections)
            {
                foreach (DocSchema docSchema in docSection.Schemas)
                {
                    foreach (DocType docType in docSchema.Types)
                    {
                        bool use = false;
                        included.TryGetValue(docType, out use);

                        if (use)
                        {
                            if (docType is DocDefined)
                            {
                                DocDefined docDefined = (DocDefined)docType;
                                string     text       = this.FormatDefinedFull(docDefined, true);
                                sb.Append(text);
                            }
                            else if (docType is DocSelect)
                            {
                                DocSelect docSelect = (DocSelect)docType;
                                string    text      = this.FormatSelectFull(docSelect, map, included, true);
                                sb.Append(text);
                            }
                            else if (docType is DocEnumeration)
                            {
                                DocEnumeration docEnumeration = (DocEnumeration)docType;
                                string         text           = this.FormatEnumerationFull(docEnumeration, true);
                                sb.Append(text);
                            }
                        }
                    }

                    foreach (DocEntity docEntity in docSchema.Entities)
                    {
                        bool use = false;
                        included.TryGetValue(docEntity, out use);

                        if (use)
                        {
                            string text = this.FormatEntityFull(docEntity, map, included, true);
                            sb.Append(text);
                        }
                    }
                }
            }
            listPropertiesOutput.Clear();
            return(sb.ToString());
        }