Example #1
0
        public void SetCell(int row, int col, CellValue val)
        {
            DocTemplateDefinition docTemplate = this.m_listTemplate[col];
            DocConceptRoot        docRoot     = this.m_view.ConceptRoots[row];

            DocTemplateUsage docConcept = null;

            foreach (DocTemplateUsage docUsage in docRoot.Concepts)
            {
                if (docUsage.Definition == docTemplate)
                {
                    docConcept = docUsage;
                    break;
                }
            }

            if (docConcept == null)
            {
                docConcept = new DocTemplateUsage();
                docRoot.Concepts.Add(docConcept);
                docConcept.Definition = docTemplate;
            }

            DocExchangeRequirementEnum req = DocExchangeRequirementEnum.NotRelevant;

            switch (val)
            {
            case CellValue.Mandatory:
                req = DocExchangeRequirementEnum.Mandatory;
                break;

            case CellValue.Recommended:
                req = DocExchangeRequirementEnum.Optional;
                break;
            }
            docConcept.RegisterExchange(this.m_exchange, req);
        }
Example #2
0
        public void SetCell(int row, int col, CellValue val)
        {
            DocTemplateDefinition docTemplate = this.m_listTemplate[row];
            DocExchangeDefinition docExchange = this.m_view.Exchanges[col];

            DocTemplateUsage docUsage = null;

            foreach (DocTemplateUsage eachUsage in this.m_root.Concepts)
            {
                if (eachUsage.Definition == docTemplate)
                {
                    docUsage = eachUsage;
                    break;
                }
            }

            if (docUsage == null)
            {
                docUsage = new DocTemplateUsage();
                this.m_root.Concepts.Add(docUsage);
                docUsage.Definition = docTemplate;
            }

            DocExchangeRequirementEnum req = DocExchangeRequirementEnum.NotRelevant;

            switch (val)
            {
            case CellValue.Required:
                req = DocExchangeRequirementEnum.Mandatory;
                break;

            case CellValue.Optional:
                req = DocExchangeRequirementEnum.Optional;
                break;
            }
            docUsage.RegisterExchange(docExchange, req);
        }
Example #3
0
        public static void Export(DocProject project, DocModelView docView, string path, Dictionary<string, DocObject> mapEntity, Dictionary<string, string> mapSchema)
        {
            Dictionary<DocObject, bool> included = docView.Filter(project);

            const string HEADERCELL = "<th style=\"-webkit-transform:rotate(90deg); writing-mode:tb-rl; -moz-transform:rotate(90deg); -o-transform: rotate(90deg); white-space:nowrap; display:blocking; ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0.083)\"; >";

            // get list of entities in order
            List<DocEntity> sortEntity = project.GetEntityList();

            // build list of templates in use (to preserve sort order)
            Dictionary<DocTemplateDefinition, List<DocConceptRoot>> mapTemplates = new Dictionary<DocTemplateDefinition, List<DocConceptRoot>>();

            // double-loop not optimal, but lists aren't that large
            foreach (DocEntity docSortEnt in sortEntity)
            {
                foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                {
                    if (docRoot.ApplicableEntity == docSortEnt)
                    {
                        foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                        {
                            if (!mapTemplates.ContainsKey(docConcept.Definition))
                            {
                                mapTemplates.Add(docConcept.Definition, new List<DocConceptRoot>());
                            }
                            mapTemplates[docConcept.Definition].Add(docRoot);
                        }
                    }
                }
            }

            // build list of concept roots sorted by entity order
            List<DocConceptRoot> sortConceptRoot = new List<DocConceptRoot>();
            foreach (DocEntity docSortEntity in sortEntity)
            {
                foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                {
                    if (docRoot.ApplicableEntity == docSortEntity)
                    {
                        sortConceptRoot.Add(docRoot);
                        break;
                    }
                }
            }

            using (FormatEXP formatEXP = new FormatEXP(path + @"\" + docView.Code + ".exp"))
            {
                formatEXP.Instance = project;
                formatEXP.ModelViews = new DocModelView[] { docView };
                formatEXP.Save();
            }

            using (FormatXSD formatXSD = new FormatXSD(path + @"\" + docView.Code + ".xsd"))
            {
                formatXSD.Instance = project;
                formatXSD.ModelViews = new DocModelView[] { docView };
                formatXSD.Save();
            }

            using (FormatSPF format = new FormatSPF(path + @"\" + docView.Code + ".ifc", Schema.IFC.SchemaIfc.Types, new Dictionary<long, SEntity>()))
            {
                format.InitHeaders(docView.Code, "IFC4");
                Schema.IFC.IfcProject ifcProject = new IfcDoc.Schema.IFC.IfcProject();
                Program.ExportIfc(ifcProject, project, included);
                format.Save();
            }

            using (FormatXML format = new FormatXML(path + @"\" + docView.Code + ".mvdxml", typeof(mvdXML), mvdXML.DefaultNamespace))
            {
                mvdXML mvd = new mvdXML();
                Program.ExportMvd(mvd, project, included);
                format.Instance = mvd;
                format.Save();
            }

            using (FormatHTM format = new FormatHTM(path + @"\" + docView.Code + ".htm", mapEntity, new Dictionary<string, string>(), included))
            {
                format.WriteHeader(docView.Name, 0, null);

                // 1 Scope
                // 1.1 Business Case Description
                // 1.2 Participants and Stakeholders

                // 2 Normative References

                // 3 Terms and definitions

                // 4 Symbols and abbreviated terms

                // 5 Business processes
                // 5.1 Process models provided
                // 5.2 Representative process models
                // 5.3 Process models formatting

                format.WriteLine("<h1>6 Exchange requirements</h1>");
                format.WriteLine("<h2>6.1 Exchange requirements legibility</h2>");
                format.WriteLine("<h3>6.1.1 Exchange requirements list</h3>");
                format.WriteLine("<p>Each exchange is listed by name as follows.</p>");
                Dictionary<string, string> mapExchangeClass = new Dictionary<string, string>();
                format.WriteLine("<ul>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    if (docExchange.ExchangeClass != null && !mapExchangeClass.ContainsKey(docExchange.ExchangeClass) && !String.IsNullOrEmpty(docExchange.ExchangeClass))
                    {
                        mapExchangeClass.Add(docExchange.ExchangeClass, docExchange.ExchangeClass);
                    }

                    format.WriteLine("<li>" + docExchange.Name + "</li>");
                }
                format.WriteLine("</ul>");

                format.WriteLine("<h3>6.1.2 Exchange requirement classification list</h3>");
                format.WriteLine("<p>Each phase classification used by this model view is listed by Omniclass notation and title as follows.</p>");
                format.WriteLine("<ul>");
                foreach (string key in mapExchangeClass.Keys)
                {
                    format.WriteLine("<li>" + key + "</li>");
                }
                format.WriteLine("</ul>");

                format.WriteLine("<h3>6.1.3 Exchange requirement coverage analysis</h3>");
                format.WriteLine("<p>Each exchange is listed by name and corresponding classifications for the process undertaken, the sender of the information, and the receiver of the information.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>Exchange</th><th>Process</th><th>Sender</th><th>Receiver</th></tr>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    format.WriteLine("<tr><td>" + docExchange.Name + "</td><td>" + docExchange.ExchangeClass + "</td><td>" + docExchange.SenderClass + "</td><td>" + docExchange.ReceiverClass);
                }
                format.WriteLine("</table>");

                format.WriteLine("<h2>6.2 Exchange requirements detail</h2>");
                format.WriteLine("<h3>6.2.1 Exchange requirements definition</h3>");
                format.WriteLine("<p>Each exchange is listed by name and a description of the information contained.</p>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    format.WriteLine("<h4>" + docExchange.Name + "</h4>");
                    format.WriteLine(docExchange.Documentation);
                }

                format.WriteLine("<h3>6.2.2 Business rule list</h3>");
                format.WriteLine("<p>Each exchange consists of a set of entity data definitions with usage defined according to business rule concepts. " +
                    "An entity describes an object class having one or more attributes, where each attribute may refer to values, collections, or references to other objects. "+
                    "A concept describes usage of object classes, where allowable values and object types are indicated for specific attributes." +
                    "Each heading that follows refers to an exchange, where each table row corresponds to an entity, each table column corresponds to an exchange, and each cell indicates whether the concept is used for the entity within the exchange.</p>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    format.WriteLine("<h4>" + docExchange.Name + "</h4>");

                    List<DocTemplateDefinition> listTemplate = project.GetTemplateList();
                    List<DocTemplateDefinition> usedTemplate = new List<DocTemplateDefinition>();

                    foreach (DocConceptRoot docRoot in docView.ConceptRoots)
                    {
                        foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                        {
                            if (!usedTemplate.Contains(docConcept.Definition))
                            {
                                foreach (DocExchangeItem docExchangeItem in docConcept.Exchanges)
                                {
                                    if (docExchangeItem.Exchange == docExchange &&
                                        (docExchangeItem.Requirement == DocExchangeRequirementEnum.Mandatory || docExchangeItem.Requirement == DocExchangeRequirementEnum.Optional))
                                    {
                                        usedTemplate.Add(docConcept.Definition);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    for(int i = listTemplate.Count - 1; i >= 0; i--)
                    {
                        if (!usedTemplate.Contains(listTemplate[i]))
                        {
                            listTemplate.RemoveAt(i);
                        }
                    }

                    format.WriteLine("<table class=\"gridtable\">");
                    format.Write("<tr>");
                    format.Write("<th>Entity</th>");
                    for (int i = 0; i < listTemplate.Count; i++)
                    {
                        format.Write(HEADERCELL);
                        format.Write(listTemplate[i].Name);
                        format.Write("</th>");
                    }
                    format.WriteLine("</tr>");

                    foreach (DocConceptRoot docRoot in sortConceptRoot)
                    {
                        DocExchangeRequirementEnum[] reqs = new DocExchangeRequirementEnum[listTemplate.Count];
                        bool include = false;
                        foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                        {
                            foreach (DocExchangeItem docExchangeItem in docConcept.Exchanges)
                            {
                                if (docExchangeItem.Exchange == docExchange &&
                                    (docExchangeItem.Requirement == DocExchangeRequirementEnum.Mandatory || docExchangeItem.Requirement == DocExchangeRequirementEnum.Optional))
                                {
                                    int index = listTemplate.IndexOf(docConcept.Definition);
                                    reqs[index] = docExchangeItem.Requirement;
                                    include = true;
                                    break;
                                }
                            }
                        }

                        if (include)
                        {
                            format.Write("<tr>");
                            format.Write("<td>" + docRoot.ApplicableEntity.Name + "</td>");
                            for (int i = 0; i < reqs.Length; i++)
                            {
                                format.Write("<td>");
                                switch (reqs[i])
                                {
                                    case DocExchangeRequirementEnum.Mandatory:
                                        format.Write("R");
                                        break;

                                    case DocExchangeRequirementEnum.Optional:
                                        format.Write("O");
                                        break;
                                }
                                format.Write("</td>");
                            }
                            format.WriteLine("</tr>");
                        }
                    }

                    format.WriteLine("</table>");
                }

                format.WriteLine("<h3>6.2.3 Business rule definition</h3>");
                format.WriteLine("<p>Business rule definitions are all defined as re-usable templates as indicated in Clause 7.3.5.</p>");

                format.WriteLine("<h2>6.3 Exchange requirements reusability</h2>");
                format.WriteLine("<p>Names and classifications of exchanges are intended to be consistent across other model views where applicable, "+
                    "while the content of a particular exchange is intended to be unique.</p>");

                format.WriteLine("<h3>6.3.1 Related business process list</h3>");
                format.WriteLine("<p>Business processes within this model view are correlated with those used in other model views as follows.</p>");

                // Rows: Business processes; Columns: Views; Cells: mark if applicable
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Process</th>");
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    format.Write(HEADERCELL + docEachView.Name + "</th>");
                }
                format.WriteLine("</tr>");
                foreach (string proc in mapExchangeClass.Keys)
                {
                    format.Write("<tr><td>" + proc + "</td>");
                    foreach (DocModelView docEachView in project.ModelViews)
                    {
                        bool yes = false;
                        foreach (DocExchangeDefinition docEachExchange in docEachView.Exchanges)
                        {
                            if (!String.IsNullOrEmpty(docEachExchange.ExchangeClass) && docEachExchange.ExchangeClass.Equals(proc))
                            {
                                yes = true;
                                break;
                            }
                        }

                        format.Write("<td>");
                        if (yes)
                        {
                            format.Write("X");
                        }
                        format.Write("</td>");
                    }
                    format.WriteLine("</tr>");
                }
                format.WriteLine("</table>");

                format.WriteLine("<h3>6.3.2 Related exchange requirement list</h3>");
                format.WriteLine("<p>Exchange requirements within this model view are correlated with those used in other model views as follows.</p>");
                // Rows: Exchanges; Columns: Views; Cells: Mark if applicable
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Exchange</th>");
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    format.Write(HEADERCELL + docEachView.Name + "</th>");
                }
                format.WriteLine("</tr>");
                foreach (DocExchangeDefinition docExchange in docView.Exchanges)
                {
                    format.Write("<tr><td>" + docExchange.Name + "</td>");
                    foreach (DocModelView docEachView in project.ModelViews)
                    {
                        bool yes = false;
                        foreach (DocExchangeDefinition docEachExchange in docEachView.Exchanges)
                        {
                            if (!String.IsNullOrEmpty(docEachExchange.Name) && docEachExchange.Name.Equals(docExchange.Name))
                            {
                                yes = true;
                                break;
                            }
                        }

                        format.Write("<td>");
                        if (yes)
                        {
                            format.Write("X");
                        }
                        format.Write("</td>");
                    }
                    format.WriteLine("</tr>");
                }
                format.WriteLine("</table>");

                format.WriteLine("<h3>6.3.3 Related exchange requirement reuse analysis</h3>");
                format.WriteLine("<p>Exchange requirements across other model views are correlated as follows.</p>");

                // Rows: Exchange names; Columns: Views; Cells: Mark if applicable
                List<string> listExchangeNames = new List<string>();
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    foreach (DocExchangeDefinition docEachExchange in docEachView.Exchanges)
                    {
                        if (!listExchangeNames.Contains(docEachExchange.Name))
                        {
                            listExchangeNames.Add(docEachExchange.Name);
                        }
                    }
                }
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Exchange</th>");
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    format.Write(HEADERCELL + docEachView.Name + "</th>");
                }
                format.WriteLine("</tr>");
                foreach (string exchangename in listExchangeNames)
                {
                    format.Write("<tr><td>" + exchangename + "</td>");
                    foreach (DocModelView docEachView in project.ModelViews)
                    {
                        bool yes = false;
                        foreach (DocExchangeDefinition docEachExchange in docEachView.Exchanges)
                        {
                            if (!String.IsNullOrEmpty(docEachExchange.Name) && docEachExchange.Name.Equals(exchangename))
                            {
                                yes = true;
                                break;
                            }
                        }

                        format.Write("<td>");
                        if (yes)
                        {
                            format.Write("X");
                        }
                        format.Write("</td>");
                    }
                    format.WriteLine("</tr>");
                }
                format.WriteLine("</table>");

                format.WriteLine("<h1>7 Model view definition</h1>");
                format.WriteLine("<h2>7.1 Data Definition</h2>");
                format.WriteLine("<h3>7.1.1 Data definitions list</h3>");
                format.WriteLine("<p>Each entity data definition is listed by schema and entity name as follows.</p>");
                format.WriteLine("<ul>");
                string lastschema = null;
                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    string schema = mapSchema[docRoot.ApplicableEntity.Name];
                    if (schema != lastschema)
                    {
                        // close out last
                        if (docRoot != sortConceptRoot[0])
                        {
                            format.WriteLine("</ul></li>");
                        }

                        // open next
                        format.WriteLine("<li>" + schema + "<ul>");

                        lastschema = schema;
                    }

                    format.WriteLine("<li>" + docRoot.ApplicableEntity.Name + "</li>");
                }
                format.WriteLine("</ul></ul>");

                format.WriteLine("<h3>7.1.2 Data definitions</h3>");
                format.WriteLine("<p>Each entity data definition is described within subsections as follows, with electronic representations provided in EXPRESS and XSD formats.</p>");
                FormatXSD formatXSD = new FormatXSD(null);
                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    string xsd = formatXSD.FormatEntity(docRoot.ApplicableEntity, mapEntity, included);

                    format.WriteLine("<h4>" + docRoot.ApplicableEntity.Name + "</h4>");
                    format.WriteLine(docRoot.ApplicableEntity.Documentation);
                    format.WriteLine("<br/>");

                    format.WriteExpressEntitySpecification(docRoot.ApplicableEntity, true, false);
                    format.WriteLine("<br/>");
                    format.WriteFormatted(xsd);
                }

                format.WriteLine("<h3>7.1.3 Data definition reference schema list</h3>");
                format.WriteLine("<p>Each referenced schema is listed by standards body notation and official title.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>Reference</th><th>Description</th></tr>");
                format.WriteLine("<tr><td>ISO 16739:2013</td><td>Industry Foundation Classes (IFC) for data sharing in the construction and facilities management industries</td></tr>");
                format.WriteLine("</table>");

                // 7.2 Concept definitions
                format.WriteLine("<h2>7.2 Concept definitions</h2>");
                format.WriteLine("<h3>7.2.1 Concept list</h3>");
                format.WriteLine("<p>Each concept is listed by entity name and concept template within the following table. "+
                    "Each row corresponds to an entity, each column corresponds to a concept template, and each cell indicates usage of a concept template for an entity.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Entity</th>");
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.Write(HEADERCELL + docTemplate.Name + "</th>");
                }
                format.WriteLine("</tr>");

                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    if (docRoot.Concepts.Count > 0)
                    {
                        format.Write("<tr><td>" + docRoot.ApplicableEntity.Name + "</td>");

                        foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                        {
                            format.Write("<td>");
                            foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                            {
                                if (docConcept.Definition == docTemplate)
                                {
                                    format.Write("X");
                                }
                            }
                            format.Write("</td>");
                        }

                        format.WriteLine("</tr>");
                    }
                }
                format.WriteLine("</table>");

                string pathImages = path + "\\" + docView.Code;
                System.IO.Directory.CreateDirectory(pathImages);

                format.WriteLine("<h3>7.2.2 Concept definitions</h3>");
                format.WriteLine("<p>Each entity is described within subsections, with diagrams indicating the graph of attributes and objects representing the combination of all concepts applied to instances of the entity. "+
                    "Each block in the diagram represents an entity, where the entity name is shown at the top of the block with background in black.  "+
                    "Each attribute within the entity is shown in order, where black is used to indicate a direct attribute and grey is used to indicate an inverse attribute. "+
                    "Notation to the right of each attribute indicates aggregation, where S indicates a SET (unordered unique objects) and L indicates a LIST (ordered objects), "+
                    "the first number in brackets indicates the minimum count, and the second number in brackets indicates the maximum count or “?” for unlimited. "+
                    "Lines connecting blocks indicates attributes that point to objects of other data definitions.</p>");
                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    format.WriteLine("<h4>" + docRoot.ApplicableEntity.Name + "</h4>");

                    string img = "";
                    if (docView.Code != null)
                    {
                        int cx = 0;
                        int cy = 0;
                        try
                        {
                            using (System.Drawing.Image image = IfcDoc.Format.PNG.FormatPNG.CreateConceptDiagram(docRoot.ApplicableEntity, docView, mapEntity, new Dictionary<System.Drawing.Rectangle,DocModelRule>(), project, null))
                            {
                                cx = image.Width;
                                cy = image.Height;
                                string filepath = path + "\\" + docView.Code.ToLower() + "\\" + docRoot.ApplicableEntity.Name.ToLower() + ".png";
                                image.Save(filepath, System.Drawing.Imaging.ImageFormat.Png);
                            }
                        }
                        catch
                        {
                        }

                        // shrink for access from MS Word
                        cx = cx / 2;
                        cy = cy / 2;

                        img = "<br/><img src=\"" + docView.Code.ToLower() + "/" + docRoot.ApplicableEntity.Name.ToLower() + ".png\" width=\"" + cx + "\" height=\"" + cy + "\"/>";
                    }

                    format.WriteLine(docRoot.Documentation);
                    format.WriteLine(img);
                    foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                    {
                        if (!String.IsNullOrEmpty(docConcept.Documentation))
                        {
                            format.WriteLine("<h5>" + docConcept.Definition.Name + "</h5>");
                            format.WriteLine(docConcept.Documentation);
                        }
                    }
                }
                format.WriteLine("</table>");

                format.WriteLine("<h3>7.2.3 Concept attributes list</h3>");
                format.WriteLine("<p>Concepts may be defined that use parameters to indicate applicable values. "+
                    "For example, plumbing objects may make use of ports to enable connectivity to other objects for distribution of water, "+
                    "and a specific entity such as a hot water heater may have specific ports such as “ColdWaterIn” and “HotWaterOut”. "+
                    "Defining attributes at concepts enables re-use of concepts where the data structures are the same, but applicable values may differ."+
                    "Each concept is shown in a subsection as follows, with rows correspoding to entities and rule instances, columns corresponding to template parameters, and cells corresponding to values applied to rules.</p>");

                // then format each template
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    string[] parameters = docTemplate.GetParameterNames();

                    if (parameters.Length > 0)
                    {
                        format.WriteLine("<h4>" + docTemplate.Name + "</h4>");
                        format.WriteLine("<table class=\"gridtable\">");
                        format.Write("<tr><th>Entity</th>");

                        foreach (string parm in parameters)
                        {
                            format.Write("<th>" + parm + "</th>");
                        }

                        format.WriteLine("</tr>");

                        List<DocConceptRoot> listRoots = mapTemplates[docTemplate];
                        foreach (DocConceptRoot docRoot in listRoots)
                        {
                            foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                            {
                                if (docConcept.Definition == docTemplate)
                                {
                                    if (docConcept.Items.Count == 0)
                                    {
                                        format.WriteLine("<tr><td>" + docRoot.ApplicableEntity.Name + "</td></tr>");
                                    }
                                    else
                                    {
                                        foreach (DocTemplateItem docItem in docConcept.Items)
                                        {
                                            if (docItem == docConcept.Items[0])
                                            {
                                                format.Write("<tr><td rowspan=\"" + docConcept.Items.Count + "\">" + docRoot.ApplicableEntity.Name + "</td>");
                                            }
                                            else
                                            {
                                                format.Write("<tr>");
                                            }

                                            foreach (string parm in parameters)
                                            {
                                                string val = docItem.GetParameterValue(parm);
                                                format.Write("<td>" + val + "</td>");
                                            }

                                            format.WriteLine("</tr>");
                                        }
                                    }
                                }
                            }
                        }

                        format.WriteLine("</table>");
                    }
                }

                format.WriteLine("<h3>7.2.4 Concept relationship description</h3>");
                format.WriteLine("<p>Concepts may inherit from other concepts such that more generic rules may be defined at a higher level and more specific rules at a lower level.  "+
                    "For example, geometry may be defined for a distribution segment (e.g. ducts, pipes, cables) that indicate permitted use of an extruded area solid (IfcExtrudedAreaSolid) "+
                    "which defines a 2D cross section extruded along a 3D linear segment. "+
                    "Such rule may be further refined for ducts to indicate that the cross-sections are further restricted to shapes such as hollow rectangles (IfcRectangleHollowProfileDef) "+
                    "or hollow circles (IfcCircleHollowProfileDef)."+
                    "Concepts are shown in a hierarchy as follows where inner concepts inherit from outer concepts.</p>");
                WriteTemplateList(format, project.Templates, included);

                format.WriteLine("<h3>7.2.5 Concept requirements applicability</h3>");
                format.WriteLine("<p>Each entity is shown in subsections as follows, with rows corresponding to concepts, columns corresponding to exchanges, "+
                    "and cells indicating requirements where 'R' indicates required and 'O' indicates optional.</p>");
                foreach (DocConceptRoot docRoot in sortConceptRoot)
                {
                    if (docRoot.Concepts.Count > 0)
                    {
                        format.WriteLine("<h4>" + docRoot.ApplicableEntity.Name + "</h4>");

                        format.WriteLine("<table class=\"gridtable\">");
                        format.Write("<tr><th>Concept</th>");
                        for (int i = 0; i < docView.Exchanges.Count; i++)
                        {
                            format.Write(HEADERCELL);
                            format.Write(docView.Exchanges[i].Name);
                            format.Write("</th>");
                        }
                        format.WriteLine("</tr>");

                        DocExchangeRequirementEnum[] reqs = new DocExchangeRequirementEnum[docView.Exchanges.Count];

                        foreach (DocTemplateUsage docConcept in docRoot.Concepts)
                        {
                            StringBuilder sbRequired = new StringBuilder();
                            StringBuilder sbOptional = new StringBuilder();
                            foreach (DocExchangeItem docExchangeItem in docConcept.Exchanges)
                            {
                                int index = docView.Exchanges.IndexOf(docExchangeItem.Exchange);
                                reqs[index] = docExchangeItem.Requirement;
                            }

                            format.Write("<tr><td>" + docConcept.Definition.Name + "</td>");
                            for (int i = 0; i < docView.Exchanges.Count; i++)
                            {
                                format.Write("<td>");
                                switch (reqs[i])
                                {
                                    case DocExchangeRequirementEnum.Mandatory:
                                        format.Write("R");
                                        break;

                                    case DocExchangeRequirementEnum.Optional:
                                        format.Write("O");
                                        break;
                                }
                                format.Write("</td>");
                            }
                            format.WriteLine("</tr>");
                        }

                        format.WriteLine("</table>");
                    }
                }

                format.WriteLine("<h2>7.3 Concept reusability</h2>");
                format.WriteLine("<h3>7.3.1 Concept list</h3>");
                format.WriteLine("<p>Each concept used within this model view is listed as follows.</p>");

                format.WriteLine("<ul>");
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.WriteLine("<li>" + docTemplate.Name + "</li>");
                }

                format.WriteLine("</ul>");

                format.WriteLine("<h3>7.3.2 Related existing concept list</h3>");
                format.WriteLine("<p>In the following table, each row corresponds to a concept used within this model view, "+
                    "each column corresponds to another model view, and each cell indicates usage of the concept within the corresponding model view.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.Write("<tr><th>Concept</th>");
                foreach (DocModelView docEachView in project.ModelViews)
                {
                    format.Write(HEADERCELL + docEachView.Name + "</th>");
                }
                format.WriteLine("</tr>");

                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.Write("<tr><td>" + docTemplate.Name + "</td>");

                    foreach (DocModelView docEachView in project.ModelViews)
                    {
                        bool yes = false;
                        foreach (DocConceptRoot docEachRoot in docEachView.ConceptRoots)
                        {
                            foreach (DocTemplateUsage docEachUsage in docEachRoot.Concepts)
                            {
                                if (docEachUsage.Definition == docTemplate)
                                {
                                    yes = true;
                                    break;
                                }
                            }
                        }

                        if (yes)
                        {
                            format.Write("<td>X</td>");
                        }
                        else
                        {
                            format.Write("<td></td>");
                        }
                    }

                    format.WriteLine("</tr>");
                }
                format.WriteLine("</table>");

                format.WriteLine("<h3>7.3.4 Concept business rule list</h3>");
                format.WriteLine("<p>Each concept template is defined in a subsection as follows, with rows corresponding to each business rule. "+
                    "The <i>Reference</i> column identifies the path to the entity and attribute. " +
                    "The <i>Cardinality</i> column indicates whether the number of permitted instances is restricted differently than the underlying schema, using [N:M] notation where N indicates the minimum number of instances, M indicates the maximum number of instances, where '?' indicates unbounded. "+
                    "The <i>Parameter</i> column indicates the name of a substitutable parameter, if applicable, defined at each usage of the business rule.<p>");
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.WriteLine("<h4>" + docTemplate.Name + "</h4>");

                    format.WriteLine("<table class=\"gridtable\">");
                    format.WriteLine("<tr><th>Reference</th><th>Cardinality</th><th>Parameter</th></tr>");

                    if (docTemplate.Rules != null)
                    {
                        foreach (DocModelRule docRule in docTemplate.Rules)
                        {
                            WriteModelRule(format, docRule, "\\" + docTemplate.Type + "." + docRule.Name);
                        }
                    }

                    format.WriteLine("</table>");
                }

                format.WriteLine("<h3>7.3.5 Concept business rule description</h3>");
                format.WriteLine("<p>Each concept template is described in a subsection as follows, with diagrams indicating usage of attributes and entities reflecting defined business rules.</p>");
                foreach (DocTemplateDefinition docTemplate in mapTemplates.Keys)
                {
                    format.WriteLine("<h4>" + docTemplate.Name + "</h4>");

                    format.WriteLine(docTemplate.Documentation);

                    string img = "";
                    if (docTemplate.Rules != null && docTemplate.Rules.Count > 0)
                    {
                        img = GenerateTemplateImage(docTemplate, mapEntity, project, path);
                        format.WriteLine(img);
                    }
                }

                format.WriteLine("<h2>7.4 Implementation</h2>");
                format.WriteLine("<h3>7.4.1 MVD Schema Listing</h3>");
                format.WriteLine("The schema encapsulating the data definitions for this model view is published in multiple representations. " +
            "<p>An MVDXML file defines the referenced entities and rules for this model view. This file may be used to validate instance data (in IFC-SPF or IFC-XML files), filter instance data to include entities and attributes within scope of this model view, or generate sub-schemas (including the EXP and XSD representations). " +
            "<p>An EXP file represents the schema in EXPRESS format (ISO 10303-11) which adapts the referenced Industry Foundation Classes schema (ISO 16739) by including a subset of data definitions and a subset of attributes within each data definition. The EXP file may be used by software development tools for generating programming languages schemas (e.g. C++, C#, Java), database definitions (e.g. SQL DDL), and data transport schema definitions (e.g. XSD). " +
            "<p>An XSD file represents the schema in XML Data Definition Language (XSD) which adapts the referenced subset of data definitions. The XSD file may be used by software development tools (e.g. Eclipse, Microsoft Visual Studio) to validate XML files and generate language-specific classes. " +
            "<p>An IFC file represents the dynamic portions of the schema in the form of property sets within an SPF (ISO 10303-21) instance file.</p>" +
            "<p>The rationale for publishing multiple representations is to provide the richest level of integration for different implementations; "+
            "while XSD is often used in defining web standards replacing document-based exchanges (e.g. invoices), it lacks data model information needed for type safety, data integrity, indexing, and optimization; "+
            "all of which may be derived from the EXPRESS representation. "+
            "</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>File</th><th>Format</th></tr>");
                format.WriteLine("<tr><td>" + docView.Code + ".exp</td><td>EXPRESS schema definition</td></tr>");
                format.WriteLine("<tr><td>" + docView.Code + ".xsd</td><td>XML schema definition (XSD)</td></tr>");
                format.WriteLine("<tr><td>" + docView.Code + ".mvdxml</td><td>MVDXML schema transform</td></tr>");
                format.WriteLine("<tr><td>" + docView.Code + ".ifc</td><td>IFC dynamic schema definition</td></tr>");
                format.WriteLine("</table>");

                format.WriteLine("<h3>7.4.2 MVD Format Description</h3>");

                format.WriteLine("<p>Implementations of this model view may publish instance data in various formats. "+
                    "Such format indicates the data encoding and does not necessarily imply that data may only be exchanged using physical files on computers; "+
                    "formats may be transmitted over the Internet as the “presentation layer” (OSI Layer 6) of any API. "+
                    "As the IFC data model supports both full and partial data models where all objects can be tagged to indicate merge directives (Create/Update/Delete using IfcOwnerHistory.ChangeAction), "+
                    "data may be transmitted in whole or in part, such as indicating only data changes.</p>");
                format.WriteLine("<p>As other OSI layers are already standardized, a full web API may be defined by referencing each layer as follows:</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>OSI Layer</th><th>OSI Layer Name</th><th>Protocol</th><th>Description</th></tr>");
                format.WriteLine("<tr><td>7</td><td>Application</td><td>WebDav</td><td>Defines valid operations such as GET, PUT, POST, DELETE, MKCOL, LOCK, UNLOCK</td></tr>");
                format.WriteLine("<tr><td>6</td><td>Presentation</td><td>IFC-SPF/IFC-XML</td><td>Defines data encoding</td></tr>");
                format.WriteLine("<tr><td>5</td><td>Session</td><td>HTTP/HTTPS</td><td>Defines establishment of sessions, compression, authentication, requests, responses, and errors</td></tr>");
                format.WriteLine("<tr><td>4</td><td>Transport</td><td>TCP</td><td>Defines message delivery</td></tr>");
                format.WriteLine("<tr><td>3</td><td>Network</td><td>IP</td><td>Defines network paths across multiple nodes</td></tr>");
                format.WriteLine("<tr><td>2</td><td>Data Link</td><td>MAC</td><td>Defines data frame communications between two nodes</td></tr>");
                format.WriteLine("<tr><td>1</td><td>Physical</td><td>(undefined)</td><td>Defines physical connectivity</td></tr>");
                format.WriteLine("</table>");

                format.WriteLine("<p>Each supported format is listed by name, with Extension indicating the default file extension to use on applicable platforms (e.g. Windows), MIME type for indicating the HTTP header when transmitting over the Internet, and Reference standard indicating the presentation layer encoding format.</p>");

                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>Format</th><th>Extension</th><th>MIME</th><th>Reference</th></tr>");
                format.WriteLine("<tr><td>IFC-SPF</td><td>.ifc</td><td>application/step</td><td>ISO 10303-21</td></tr>");
                format.WriteLine("<tr><td>IFC-XML</td><td>.ifcxml</td><td>application/xml</td><td>ISO 10303-28</td></tr>");
                format.WriteLine("</table>");

                format.WriteLine("<p>IFC-SPF (ISO 10303-21) is a text format optimized to carry data with complex relationships, supporting human readability yet more compact representation (typically around 10% of size of equivalent XML).</p>");

                format.WriteLine("<p>IFC-HDF (ISO 10303-26) is a binary file format encapsulating data in a compact, indexable encoding optimized for quick retrieval and minimal memory usage. ");
                format.WriteLine("<blockquote class=\"note\">NOTE&nbsp; As this file type is not yet widely implemented, it is not officially part of this model view, however implementations may prefer such format for internal use.</blockquote>");

                format.WriteLine("<p>IFC-XML (ISO 10303-28) is a hierarchical markup format with wide support from software development tools and platforms, supporting greater human readability at the expense of larger representation.  </p>");
                format.WriteLine("<blockquote class=\"note\">NOTE&nbsp; As typical buildings contain millions of elements with graphs of relationships resulting in gigabytes of data, " +
            "XML is not yet suitable for representing complete buildings from a pragmatic standpoint of data size, transmission cost, and loading time. " +
            "However, using derived formats along with MVDXML to filter data sets may enable more efficient exchanges to take place.</blockquote>");

                format.WriteLine("<p>IFC-ZIP (ISO 21320-1) is a compressed file format encapsulating one of the above formats to minimize data size. ");
                format.WriteLine("<blockquote class=\"note\">NOTE&nbsp; As this model view is primarily intended for web-based exchange, zip compression may be selected by other means according to the client and server; therefore, the IFC-ZIP format is not officially part of this model view.</blockquote>");

                format.WriteLine("<h3>7.4.3 MVD Dynamic Schema Analysis</h3>");
                format.WriteLine("<p>Portions of data definitions are defined dynamically, to allow software applications to support extensible definitions while minimizing implementation overhead. "+
                    "Each property set is shown within a subsection as follows, with rows corresponding to properties. See <i>IfcPropertySet</i> for usage information.</p>");
                foreach (DocSection docSection in project.Sections)
                {
                    foreach (DocSchema docSchema in docSection.Schemas)
                    {
                        foreach (DocPropertySet docPset in docSchema.PropertySets)
                        {
                            if (included == null || included.ContainsKey(docPset))
                            {
                                format.WriteLine("<h4>" + docPset.Name + "</h4>");
                                format.WriteLine("<table class=\"gridtable\">");
                                format.WriteLine("<tr><th>Property</th><th>Property Type</th><th>Data Type</th><th>Description</th></tr>");

                                foreach (DocProperty docProp in docPset.Properties)
                                {
                                    string datatype = docProp.PrimaryDataType;
                                    if (!String.IsNullOrEmpty(docProp.SecondaryDataType))
                                    {
                                        datatype += "/" + docProp.SecondaryDataType;
                                    }

                                    format.WriteLine("<tr><td>" + docProp.Name + "</td><td>" + docProp.PropertyType + "</td><td>" + datatype + "</td><td>" + docProp.Documentation + "</td></tr>");
                                }

                                format.WriteLine("</table>");
                            }
                        }
                    }
                }

                format.WriteLine("<h3>7.4.4 Non-Applicable Entity Exclusion Analysis</h3>");
                format.WriteLine("<p>The referenced IFC schema is shown in the following table, with each row corresponding to a schema namespace, with data definitions listed within, where bold items indicate definitions within scope of this Model View Definition.</p>");
                format.WriteLine("<table class=\"gridtable\">");
                format.WriteLine("<tr><th>Namespace</th><th>Definitions</th><th>Usage</th></tr>");
                foreach (DocSection docSection in project.Sections)
                {
                    if (docSection.Schemas.Count > 0)
                    {
                        foreach (DocSchema docSchema in docSection.Schemas)
                        {
                            format.Write("<tr><td>" + docSchema.Name + "</td><td>");

                            int min = 0;
                            int max = 0;

                            foreach (DocEntity docEntity in docSchema.Entities)
                            {
                                max++;
                                if (included == null || included.ContainsKey(docEntity))
                                {
                                    min++;
                                    format.Write("<b>");
                                }
                                format.Write(docEntity.Name);
                                format.Write("; ");
                                if (included == null || included.ContainsKey(docEntity))
                                {
                                    format.Write("</b>");
                                }
                            }

                            foreach (DocType docType in docSchema.Types)
                            {
                                max++;
                                if (included == null || included.ContainsKey(docType))
                                {
                                    min++;
                                    format.Write("<b>");
                                }
                                format.Write(docType.Name);
                                format.Write("; ");
                                if (included == null || included.ContainsKey(docType))
                                {
                                    format.Write("</b>");
                                }
                            }

                            format.Write("</td>");

                            format.Write("<td>" + min + "/" + max + " (" + (100.0 *(double)min/(double)max).ToString("N0") + "%)</td>");

                            format.WriteLine("</tr>");

                        }
                    }
                }
                format.WriteLine("</table>");

                // 8 Conformance testing procedures

                // 9 Implementation resources

                // 10 Revision Plans

                format.WriteFooter("");
            }
        }
Example #4
0
        private void ApplyExchangeRequirement(DocExchangeApplicabilityEnum applicability, DocExchangeRequirementEnum requirement)
        {
            if (m_loadreq)
                return;

            // commit changes

            DocTemplateUsage docUsage = (DocTemplateUsage)this.m_target;

            foreach (ListViewItem lvi in this.listViewExchange.SelectedItems)
            {
                DocExchangeDefinition docExchange = (DocExchangeDefinition)lvi.Tag;

                // find existing  
                bool exists = false;
                foreach (DocExchangeItem docItem in docUsage.Exchanges)
                {
                    if (docItem.Exchange == docExchange && docItem.Applicability == applicability)
                    {
                        // found it
                        if (requirement == DocExchangeRequirementEnum.NotRelevant)
                        {
                            // delete item (reduce size)
                            docUsage.Exchanges.Remove(docItem);
                            docItem.Delete();
                        }
                        else
                        {
                            // update item
                            docItem.Requirement = requirement;
                        }
                        exists = true;
                        break; // perf, and collection may have been modified
                    }
                }

                if (!exists)
                {
                    DocExchangeItem docItem = new DocExchangeItem();
                    docItem.Exchange = docExchange;
                    docItem.Applicability = applicability;
                    docItem.Requirement = requirement;
                    docUsage.Exchanges.Add(docItem);
                }

                // update list
                if (applicability == DocExchangeApplicabilityEnum.Import)
                {
                    lvi.SubItems[1].Text = requirement.ToString();
                }
                else if (applicability == DocExchangeApplicabilityEnum.Export)
                {
                    lvi.SubItems[2].Text = requirement.ToString();
                }
            }            
        }
Example #5
0
        private void LoadExchangeRequirement(RadioButton button, DocExchangeApplicabilityEnum applicability, DocExchangeRequirementEnum requirement)
        {
            DocTemplateUsage docUsage = (DocTemplateUsage)this.m_target;

            bool? common = null; // the common value
            bool varies = false; // whether value varies among objects

            foreach (ListViewItem lvi in this.listViewExchange.SelectedItems)
            {
                DocExchangeDefinition docDef = (DocExchangeDefinition)lvi.Tag;

                // find exchange on usage
                foreach (DocExchangeItem docItem in docUsage.Exchanges)
                {
                    if (docItem.Exchange == docDef && docItem.Applicability == applicability)
                    {
                        bool eachval = (docItem.Requirement == requirement);
                        if (common == null)
                        {
                            common = eachval;
                        }
                        else if (common != eachval)
                        {
                            varies = true;
                        }
                    }
                }
            }

            this.m_loadreq = true;
            button.Checked = (common == true && !varies);
            this.m_loadreq = false;
        }
        private static void AppendRequirement(StringBuilder sb, DocExchangeRequirementEnum req, int level)
        {
            // new-style character (allows copy/paste into word without slowdown)
            switch (req)
            {
                case DocExchangeRequirementEnum.Excluded:
                    sb.Append("X");
                    break;

                case DocExchangeRequirementEnum.Mandatory:
                    sb.Append("R");
                    break;

                case DocExchangeRequirementEnum.NotRelevant:
                    sb.Append("-");
                    break;

                case DocExchangeRequirementEnum.Optional:
                    sb.Append("O");
                    break;
            }
        }
Example #7
0
        /// <summary>
        /// Recursively validates a concept and all referenced concepts
        /// </summary>
        /// <param name="docUsage">The concept to validate</param>
        /// <param name="docView">The model view containing the concept</param>
        /// <param name="reqInherit">For a referenced concept, indicates requirements defined by the referencing (outer) concept.</param>
        /// <param name="typeEntity">The compiled type corresponding to entity.</param>
        /// <param name="list">List of entities to test for concept.</param>
        /// <param name="sb">String builder to append for reporting results.</param>
        /// <param name="typemap">Map of identifiers to compiled types</param>
        /// <param name="grandtotalpass">The total tests passing (less than or equal to total tests executed).</param>
        /// <param name="grandtotallist">The total tests executed.</param>
        private void ValidateConcept(DocTemplateUsage docUsage, DocModelView docView, DocExchangeRequirementEnum reqInherit, Type typeEntity, List<SEntity> list, StringBuilder sb, Dictionary<string, Type> typemap, ref int grandtotalpass, ref int grandtotalskip, ref int grandtotallist)
        {
            if (docUsage.Definition == null || docUsage.Definition.IsDisabled || docUsage.Suppress)
                return;

            DocExchangeRequirementEnum req = DocExchangeRequirementEnum.NotRelevant;
            bool includeconcept = true;
            if (this.m_filterexchange != null)
            {
                includeconcept = false;
                foreach (DocExchangeItem ei in docUsage.Exchanges)
                {
                    if (ei.Exchange == this.m_filterexchange && ei.Applicability == DocExchangeApplicabilityEnum.Export &&
                        (ei.Requirement == DocExchangeRequirementEnum.Mandatory || ei.Requirement == DocExchangeRequirementEnum.Optional))
                    {
                        includeconcept = true;
                        req = ei.Requirement;
                    }
                }
            }
            else
            {
                // check net requirement if mandatory for any exchange
                foreach (DocExchangeItem docExchangeItem in docUsage.Exchanges)
                {
                    switch (docExchangeItem.Requirement)
                    {
                        case DocExchangeRequirementEnum.Mandatory:
                            req = DocExchangeRequirementEnum.Mandatory;
                            break;

                        case DocExchangeRequirementEnum.Optional:
                            if (req == DocExchangeRequirementEnum.NotRelevant)
                            {
                                req = DocExchangeRequirementEnum.Optional;
                            }
                            break;

                        case DocExchangeRequirementEnum.Excluded:
                            if (req == DocExchangeRequirementEnum.NotRelevant)
                            {
                                req = DocExchangeRequirementEnum.Excluded;
                            }
                            break;
                    }
                }
            }

            if (req == DocExchangeRequirementEnum.NotRelevant)
            {
                req = reqInherit;
                if (reqInherit != DocExchangeRequirementEnum.NotRelevant)
                {
                    includeconcept = true;
                }
            }

            if (!includeconcept)
                return;

            if (list.Count == 0)
            {
                sb.Append("<details><summary>");
                sb.Append(docUsage.Definition.Name);
                sb.AppendLine("</summary></details>");
                return;
            }

            StringBuilder sbDetail = new StringBuilder();

            if (docUsage.Definition != null && docUsage.Definition.Rules != null)
            {
                // new-style validation -- compiled code (fast)
                string methodname = DocumentationISO.MakeLinkName(docView) + "_" + DocumentationISO.MakeLinkName(docUsage.Definition);
                System.Reflection.MethodInfo method = typeEntity.GetMethod(methodname);

                int fail = 0;
                int pass = 0; // pass graph check
                int passRule = 0; // pass rule check
                int failRule = 0; // fail rule check
                List<DocModelRule> trace = new List<DocModelRule>();

                DocModelRule[] parameterrules = docUsage.Definition.GetParameterRules();
                Dictionary<DocModelRuleAttribute, bool> conditions = new Dictionary<DocModelRuleAttribute, bool>();

                if (docUsage.Definition.Name.Contains("-086"))
                {
                    this.ToString();
                }

                foreach (SEntity ent in list)
                {
                    if(docUsage.Definition.Name.Contains("-077") && ent.GetType().Name.Equals("IfcWindow"))
                    {
                        this.ToString();
                    }

                    object[] args = new object[0];
                    if (parameterrules != null && parameterrules.Length > 0)
                    {
                        args = new object[parameterrules.Length];

                        foreach (DocTemplateItem docItem in docUsage.Items)
                        {
                            //if (!docItem.Optional)
                            {
                                trace.Clear();
                                conditions.Clear();

                                if (docItem == docUsage.Items[0])
                                {
                                    sbDetail.Append("<tr valign=\"top\"><td rowspan=\"" + docUsage.Items.Count + "\">#");
                                    sbDetail.Append(ent.OID);
                                    sbDetail.Append("</td>");
                                }
                                else
                                {
                                    sbDetail.Append("<tr valign=\"top\">");
                                }

                                for (int iParam = 0; iParam < parameterrules.Length; iParam++)
                                {
                                    DocModelRule prule = parameterrules[iParam];

                                    sbDetail.Append("<td>");
                                    DocTemplateUsage docUsageInner = docItem.GetParameterConcept(prule.Identification, null);//verify...
                                    if (docUsageInner != null)
                                    {
                                        // report inner rules...
                                        foreach (DocTemplateItem docItemInner in docUsageInner.Items)
                                        {
                                            sbDetail.Append(docItemInner.RuleParameters);
                                            if (docItemInner.Optional)
                                            {
                                                sbDetail.Append("*");
                                            }
                                            sbDetail.Append("<br/>");
                                        }
                                    }
                                    else
                                    {
                                        string pval = docItem.GetParameterValue(prule.Identification);
                                        sbDetail.Append(pval);
                                    }
                                    sbDetail.Append("</td>");
                                }

                                sbDetail.Append("<td>");
                                bool? result = true;
                                foreach (DocModelRule rule in docUsage.Definition.Rules)
                                {
                                    trace.Clear();
                                    bool? itemresult = rule.Validate(ent, docItem, typemap, trace, ent, docUsage, conditions);
                                    if (itemresult != null && !itemresult.Value && result != null)
                                    {
                                        result = false;

                                        // check if conditions were all met; if not, then not a failure
                                        foreach(DocModelRule checkparam in parameterrules)
                                        {
                                            if(checkparam.IsCondition())
                                            {
                                                bool paramspec = false;
                                                if (!conditions.TryGetValue((DocModelRuleAttribute)checkparam, out paramspec) || paramspec == false)
                                                {
                                                    result = null;
                                                    break;
                                                }
                                            }
                                        }

                                        break;
                                    }
                                    else if (itemresult == null)
                                    {
                                        result = null; //verify: was commented out -- put back in to indicate that entire rule is inapplicable.
                                    }
                                }

                                if (result != null && !result.Value)
                                {
                                    foreach (DocModelRule mm in trace)
                                    {
                                        if (mm is DocModelRuleEntity)
                                        {
                                            sbDetail.Append("\\");
                                        }
                                        else if (mm is DocModelRuleAttribute)
                                        {
                                            sbDetail.Append(".");
                                        }
                                        sbDetail.Append(mm.Name);
                                    }

                                    docItem.ValidationStructure[ent] = false;

            #if false // don't mark overall usage as failure, since operator may only require one to be true
                                    if (!docItem.Optional)
                                    {
                                        docUsage.ValidationStructure[ent] = false;
                                        docUsage.Validation = false;
                                        docUsage.Definition.Validation = false;
                                        fail++;
                                    }
            #endif
                                }
                                else if (result != null && result.Value)
                                {
                                    // check for any nested failures
                                    foreach (DocTemplateUsage docInnerConcept in docItem.Concepts)
                                    {
                                        foreach (DocTemplateItem docInnerItem in docInnerConcept.Items)
                                        {
                                            bool innerresult = false;
                                            if(docInnerItem.ValidationStructure.TryGetValue(ent, out innerresult))
                                            {
                                                if(!innerresult)
                                                {
                                                    sbDetail.Append("~");
                                                    sbDetail.Append(docInnerItem.RuleParameters);
                                                    sbDetail.Append("<br/>");

                                                    result = false;
                                                    fail++;
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    if (result != null && result.Value)
                                    {
                                        sbDetail.Append("+");
                                        pass++;

                                        docItem.ValidationStructure[ent] = true;
                                        if (!docUsage.ValidationStructure.ContainsKey(ent)) // if no failures so far, then concept passes for now
                                        {
                                            docUsage.ValidationStructure[ent] = true;
                                        }
                                    }
                                }
                                else if (result == null)
                                {
                                    sbDetail.Append("*"); // NOT APPLICABLE

                                    // new V9.5: don't mark non-applicable as passing
                                    /*
                                    docItem.ValidationStructure[ent] = true;
                                    if (!docUsage.ValidationStructure.ContainsKey(ent))
                                    {
                                        docUsage.ValidationStructure[ent] = true;
                                    }*/
                                }

                                sbDetail.Append("</td><td>");

                                if (result == null)
                                {
                                    // don't evaluate constraint if it doesn't apply
                                }
                                else if (method != null)
                                {
                                    try
                                    {
                                        bool[] ruleresult = (bool[])method.Invoke(ent, null);//, args);
                                        if (ruleresult != null)
                                        {
                                            bool allpass = true;
                                            foreach (bool compresult in ruleresult)
                                            {
                                                if (!compresult)
                                                {
                                                    allpass = false;
                                                    break;
                                                }
                                            }

                                            if (allpass)
                                            {
                                                sbDetail.Append("+");
                                                passRule++;

                                                docUsage.ValidationConstraints[ent] = true;

                                                if (docUsage.Validation == null)
                                                {
                                                    docUsage.Validation = true;
                                                }
                                            }
                                            else
                                            {
                                                // run detailed report
                                                foreach (DocModelRule rule in docUsage.Definition.Rules)
                                                {
                                                    TraceRule(docUsage.Definition, rule, sbDetail, ent, list);
                                                }

                                                failRule++;

                                                docUsage.ValidationConstraints[ent] = false;
                                                docUsage.Validation = false;
                                            }
                                        }
                                        else
                                        {
                                            sbDetail.Append("FAIL");
                                            failRule++;
                                        }
                                    }
                                    catch (System.Reflection.TargetInvocationException et)
                                    {
                                        sbDetail.Append(et.InnerException.GetType().Name);
                                        failRule++;
                                    }
                                    catch (Exception ex)
                                    {
                                        sbDetail.Append(ex.GetType().Name);
                                        failRule++;
                                    }
                                }
                                else
                                {
                                    sbDetail.Append("FAIL - Incompatible Template");
                                }

                                sbDetail.AppendLine("</td></tr>");
                            }
                        }

                        // capture items that didn't match
                    }
                    else
                    {
                        // check for if there are no parameters

                        sbDetail.Append("<tr valign=\"top\"><td>#");
                        sbDetail.Append(ent.OID);
                        sbDetail.Append("</td><td>");

                        DocModelRule ruleFail = null;
                        bool? result = true;
                        foreach (DocModelRule rule in docUsage.Definition.Rules)
                        {
                            trace.Clear();
                            bool? itemresult = rule.Validate(ent, null, typemap, trace, ent, docUsage, conditions);
                            if (itemresult != null && !itemresult.Value)
                            {
                                result = false;
                            }
                            else if (itemresult == null)
                            {
                                result = null;
                            }

                            if (itemresult != null && !itemresult.Value)
                            {
                                if (ruleFail != null)
                                {
                                    sbDetail.Append("<br/>");
                                }
                                ruleFail = rule;

                                foreach (DocModelRule mm in trace)
                                {
                                    if (mm is DocModelRuleEntity)
                                    {
                                        sbDetail.Append("\\");
                                    }
                                    else if (mm is DocModelRuleAttribute)
                                    {
                                        sbDetail.Append(".");
                                    }
                                    sbDetail.Append(mm.Name);
                                }
                            }
                        }

                        if (result == null)
                        {
                            // no applicable rules, so passing
                            pass++;
                        }
                        else if (result != null && result.Value)
                        {
                            // all rules passed
                            docUsage.ValidationStructure[ent] = true;
                            if (docUsage.Validation == null)
                            {
                                docUsage.Validation = true;
                            }
                            pass++;
                        }
                        else if (ruleFail != null)
                        {
                            docUsage.ValidationStructure[ent] = false;
                            docUsage.Validation = false;
                            fail++;
                        }

                        if (result == null)
                        {
                            sbDetail.Append("*");
                        }
                        else if (ruleFail == null)
                        {
                            sbDetail.Append("+");
                        }

                        sbDetail.Append("</td><td>");

                        if (method != null)
                        {
                            try
                            {
                                bool[] ruleresult = (bool[])method.Invoke(ent, args);
                                if (ruleresult != null)
                                {
                                    bool allpass = true;
                                    foreach (bool compresult in ruleresult)
                                    {
                                        if (!compresult)
                                        {
                                            allpass = false;
                                            break;
                                        }
                                    }

                                    if (allpass)
                                    {
                                        sbDetail.Append("+");
                                        docUsage.ValidationConstraints[ent] = true;
                                        passRule++;
                                    }
                                    else
                                    {
                                        // run second-stage validation and trace
                                        bool debugpass = true;
                                        StringBuilder sbCheck = new StringBuilder();
                                        foreach (DocModelRule rule in docUsage.Definition.Rules)
                                        {
                                            bool eachpass = TraceRule(docUsage.Definition, rule, sbCheck, ent, list);
                                            if (!eachpass)
                                            {
                                                debugpass = false;
                                            }
                                        }
                                        if (!debugpass)
                                        {
                                            sbDetail.Append(sbCheck.ToString());
                                            docUsage.ValidationConstraints[ent] = false;
                                            docUsage.Validation = false;
                                            failRule++;
                                        }
                                        else
                                        {
                                            sbDetail.Append("+");
                                            docUsage.ValidationConstraints[ent] = true;
                                            if (docUsage.Validation == null)
                                            {
                                                docUsage.Validation = true;
                                            }
                                            passRule++;
                                        }
                                    }
                                }
                                else
                                {
                                    sbDetail.Append("FAIL");
                                    failRule++;
                                }
                            }
                            catch (System.Reflection.TargetInvocationException et)
                            {
                                sbDetail.Append(et.InnerException.GetType().Name);
                                failRule++;
                            }
                            catch (Exception ex)
                            {
                                sbDetail.Append(ex.GetType().Name);
                                failRule++;
                            }
                        }
                        else
                        {
                            sbDetail.Append("FAIL - Incompatible Template");
                        }
                        sbDetail.AppendLine("</td></tr>");
                    }

                }

                grandtotallist++;

                // nested concepts -- only one must pass
                StringBuilder sbNested = new StringBuilder();
                if (docUsage.Concepts.Count > 0)
                {
                    sbNested.AppendLine("<p>Validation of concept groups (only one must pass):</p>");

                    int subtotalpass = 0;
                    int subtotalskip = 0;
                    int subtotallist = 0;
                    foreach (DocTemplateUsage docSub in docUsage.Concepts)
                    {
                        ValidateConcept(docSub, docView, reqInherit, typeEntity, list, sbNested, typemap, ref subtotalpass, ref subtotalskip, ref subtotallist);
                    }

                    if (subtotalpass > 0)
                    {
                        //grandtotalpass++;
                        sbNested.AppendLine("<p>RESULT: PASS (" + subtotalpass + "/" + subtotallist + ")</p>");
                    }
                    else
                    {
                        fail++;
                        sbNested.AppendLine("<p>RESULT: FAIL (" + subtotalpass + "/" + subtotallist + ")</p>");
                    }
                }

                sb.AppendLine("<details><summary>" + docUsage.Definition.Name);

                sb.Append(" (Operator: " + docUsage.Operator.ToString() + ")");

                if(req == DocExchangeRequirementEnum.Optional)
                {
                    sb.Append(" [OPTIONAL]");
                }
                if (fail > 0 || failRule > 0)
                {
                    docUsage.Validation = false;
                    docUsage.Definition.Validation = false;

                    if(req == DocExchangeRequirementEnum.Optional)
                    {
                        grandtotalskip++;
                    }

                    sb.AppendLine(" - [FAIL]");
                }
                else
                {
                    docUsage.Validation = true;
                    if (docUsage.Definition.Validation == null)
                    {
                        docUsage.Definition.Validation = true;
                    }

                    grandtotalpass++;
                }

                sb.AppendLine("</summary>");
                sb.AppendLine("<table border=\"1\" >");
                sb.Append("<tr><th>Instance</th>");

                foreach (DocModelRule docRule in parameterrules)
                {
                    sb.Append("<th>");
                    sb.Append(docRule.Identification);

                    if (docRule.IsCondition())
                    {
                        sb.Append("?");
                    }

                    sb.Append("</th>");
                }

                sb.Append("<th>Structure</th>");
                sb.Append("<th>Constraints</th>");
                sb.AppendLine("</tr>");

                sb.AppendLine(sbDetail.ToString());

                sb.AppendLine("</table>");

                sb.AppendLine(sbNested.ToString());

                sb.AppendLine("</details>");
            }
        }
Example #8
0
        /// <summary>
        /// Appends result to string, returns boolean of pass or failure.
        /// </summary>
        /// <param name="sb"></param>
        /// <param name="pass"></param>
        /// <param name="count"></param>
        /// <param name="req"></param>
        /// <returns></returns>
        private static bool AppendResult(StringBuilder sb, int pass, int count, DocExchangeRequirementEnum req)
        {
            switch (req)
            {
                case DocExchangeRequirementEnum.Mandatory:
                    if (pass == count)
                    {
                        sb.Append("+");
                        return true;
                    }
                    else
                    {
                        sb.Append("F");
                        return false;
                    }

                case DocExchangeRequirementEnum.Excluded:
                    if (pass != 0)
                    {
                        sb.Append("F");
                        return false;
                    }
                    else
                    {
                        sb.Append("+");
                        return true;
                    }

                case DocExchangeRequirementEnum.Optional:
                    if (pass == count)
                    {
                        sb.Append("+");
                    }
                    else
                    {
                        sb.Append("*");
                    }
                    return true;

                case DocExchangeRequirementEnum.NotRelevant:
                    sb.Append("-");
                    return true;
            }

            return false;
        }