Example #1
0
         private static Slot _createBodySlot(BplProperty parentProperty, BplClass bplClass, Stack<BplClass> parentClasses) {
            if (parentClasses.Any(pclass => bplClass.IsA(pclass))) {
               var error = new Record("", parentProperty.Name + " : " + bplClass.Name + " [recursive]");
               return new Slot(error, _slotErrorBG);
            }
            parentClasses.Push(bplClass);

            var childSlots = new StackPanel {
               Margin = new Thickness(0, _slotSize, _slotSize, 0)
            };

            childSlots.Children.Add(new Slot(0, new Record("4", "Opcode (<c>0x{0:X8}</c>)".Substitute(bplClass.Protocol.Opcode))));

            var depth = 0;
            int? fixedSize = 4;
            foreach (var prop in bplClass.Properties) {
               Slot slot = null;
               if (prop.IsCalculated) continue;
               if (prop.IsPrimitive) {
                  var ptype = prop.PrimitiveType;
                  var pname = "{0} : <i>{1}</i>".Substitute(prop.Name, (ptype.IsDelegate ? "Function" : ptype.Name));
                  var psize = BplLanguage.BinaryConverters[ptype].SizeOf();
                  if (psize.Size.HasValue && fixedSize.HasValue) {
                     fixedSize = fixedSize.Value + psize.Size.Value;
                  } else {
                     fixedSize = null;
                  }
                  slot = new Slot(0, new Record(psize.Formula, pname));
               } else {
                  fixedSize = null;
                  var refClass = prop.ReferencedClass;
                  if (prop.IsAssociation) {
                     var multiplier = "";
                     var suffix = "*";
                     if (prop.IsCollection) {
                        multiplier = @"n {0} ".Substitute(DOT);
                        suffix = "[]";
                     }
                     var record = new Record("4 + {0}|id|".Substitute(multiplier), "{0} : <i>{1}{2}</i>".Substitute(prop.Name, refClass.Name, suffix));
                     slot = new Slot(0, record);
                  } else {
                     slot = _createBodySlot(prop, refClass, parentClasses);
                  }
               }
               depth = Math.Max(depth, slot.Depth);
               childSlots.Children.Add(slot);
            }

            var parentGrid = new Grid();
            parentGrid.Children.Add(childSlots);

            if (parentProperty == null) {
               var title = new HtmlBlock("<b>{0}</b>".Substitute(bplClass.Name)) {
                  Margin = new Thickness(_slotMargin),
                  HorizontalAlignment = HorizontalAlignment.Center,
                  VerticalAlignment = VerticalAlignment.Top
               };
               parentGrid.Children.Add(title);
               _ncollections = 0;
            } else {
               var name = "{0} : <i>{1}</i>".Substitute(parentProperty.Name, bplClass.Name + (parentProperty.IsCollection ? "[]" : "*"));
               var cardinality = "1";
               if (parentProperty.IsCollection) {
                  cardinality = @"N<font size=""8"">{0}</font>".Substitute(++_ncollections);
               }

               var parentSize = String.Empty;
               if (fixedSize.HasValue) {
                  parentSize = fixedSize.Value.ToString();
               } else {
                  parentSize = "|{0}|".Substitute(_getNameStem(bplClass.Name));
               }
               if (cardinality == "1") {
                  parentSize = "4 + {0}?".Substitute(parentSize);
               } else {
                  parentSize = "4 + {0} {1} {2}".Substitute(cardinality, DOT, parentSize);
               }
               parentGrid.Children.Add(new Record(parentSize, name));

               parentGrid.Children.Add(new HtmlBlock(cardinality) {
                  Width = _slotSize,
                  TextAlignment = TextAlignment.Center,
                  HorizontalAlignment = HorizontalAlignment.Right,
                  VerticalAlignment = VerticalAlignment.Center
               });
            }

            parentClasses.Pop();
            return new Slot(depth + 1, parentGrid);
         }
      /// <summary>Add tool extentions for class.</summary>
      private void AddToolExtensions(BplClass bplClass) {

         string stereotype = string.Empty;

         // Class stereotypes and tags
         XElement xTags = new XElement("tags");

         if (bplClass.IsA<BplMessage>()) {
            stereotype = "bplMessage";
            string kind = (bplClass.Protocol.IsRequest) ? "request" :
                          (bplClass.Protocol.IsResponse) ? "response" :
                          (bplClass.Protocol.IsNotification) ? "notification" : "unknown";

            xTags.AddTags(
               new Pair("opCode", bplClass.Protocol.Opcode),
               new Pair("serviceOperationKind", kind)
               );

         } else if (bplClass.IsA<BplEntity>()) {
            stereotype = "bplEntity";
            xTags.AddTags(new Pair("opCode", bplClass.Protocol.Opcode));

         } else {
            stereotype = "bplPrimitive";
         }

         // Add the element extensions
         XElement xElementExt = new XElement("element",
             new XAttribute(xmiNs + "idref", bplClass.GetID()),
             new XAttribute(xmiNs + "type", "uml:Class"),
             new XAttribute("name", bplClass.Name),
             new XAttribute("scope", "public"));

         var documentation = BplLanguage.Documentation[bplClass].Content;
         xElementExt.Add(new XElement("properties",
            new XAttribute("documentation", (documentation != null ? documentation.Value : "")),
            new XAttribute("isSpecification", "false"),
            new XAttribute("sType", "Class"),
            new XAttribute("alias", bplClass.CanonicName),
            new XAttribute("scope", "public"),
            new XAttribute("stereotype", stereotype),
            new XAttribute("isAbstract", bplClass.IsConcrete ? "false" : "true"),
            new XAttribute("isRoot", (bplClass.BaseClass == null) ? "true" : "false"),
            new XAttribute("isActive", "true")
            ));

         // Add tags
         xElementExt.Add(xTags);


         // Add Links
         XElement xLinks = new XElement("links");

         // Add generalization link to the parent class
         if (bplClass.BaseClass != null) {
            string genId = string.Format("EAID_{0}_ISA_{1}", bplClass.GetID(), bplClass.BaseClass.GetID());
            XElement xGeneralization = new XElement("generalization",
                new XAttribute(xmiNs + "id", genId),
                new XAttribute("start", bplClass.GetID()),
                new XAttribute("end", bplClass.BaseClass.GetID()));
            xLinks.Add(xGeneralization);
         }

         // Add generalization link to all derived classes
         bplClass.DerivedClasses.Apply<BplClass>(cls => {
            string genId = string.Format("EAID_{0}_ISA_{1}", cls.GetID(), bplClass.GetID());
            XElement xGeneralization = new XElement("generalization",
                new XAttribute(xmiNs + "id", genId),
                new XAttribute("start", cls.GetID()),
                new XAttribute("end", bplClass.GetID()));
            xLinks.Add(xGeneralization);
         });

         xElementExt.Add(xLinks);

         // Add Properties Extensions
         XElement xAttributes = new XElement("attributes");
         xElementExt.Add(xAttributes);
         bplClass.OwnProperties.Apply<BplProperty>(pr => AddToolExtensions(pr, xAttributes));
         XmiElements.Add(xElementExt);
      }
 private Inline _formatClassType(BplClass bplClass) {
    var text = "";
    if (bplClass.Operation != null) {
       text = "Service";
    } else if (bplClass.IsA<BplStructure>()) {
       text = "Structure";
    } else if (bplClass.IsA<BplMessage>()) {
       text = "Message";
    } else if (bplClass.IsA<BplTaxonomy>()) {
       text = "Taxonomy";
    } else if (bplClass.IsA<BplEntity>()) {
       text = "Entity";
    } else {
       text = "Object";
    }
    var span = new Span(new Run(text));
    if (!bplClass.IsConcrete) {
       span.FontStyle = FontStyles.Italic;
    }
    return span;
 }
      /// <summary>Add uml extentions for class.</summary>
      private void AddUmlExtensions(BplClass bplClass) {

         ulong opCode = (ulong)bplClass.Protocol.Opcode;
         if (bplClass.IsA<BplMessage>()) {
            string kind = (bplClass.Protocol.IsRequest) ? "request" :
                          (bplClass.Protocol.IsResponse) ? "response" :
                          (bplClass.Protocol.IsNotification) ? "notification" : "unknown";

            AddUmlExtentions("bplMessage", BASE_CLASS, bplClass.GetID(),
               new Pair("opCode", bplClass.Protocol.Opcode),
               new Pair("serviceOperationKind", kind)
               );
         } else if (bplClass.IsA<BplEntity>()) {
            AddUmlExtentions("bplEntity", BASE_CLASS, bplClass.GetID(), new Pair("opCode", opCode));
         } else if (bplClass.IsA<BplStructure>()) {
            AddUmlExtentions("bplStructure", BASE_CLASS, bplClass.GetID(), new Pair("opCode", opCode));
         } else {
            AddUmlExtentions("bplPrimitive", BASE_CLASS, bplClass.GetID(), new Pair("opCode", opCode));
         }

         // Add the profile extension for the class properties
         bplClass.OwnProperties.Apply<BplProperty>(prop => AddUmlExtensions(prop));
      }
      private Block _formatPropertiesTable(string header, BplClass bplClass) {
         if (bplClass == null) return null;
         var table = new TableData("*", "*", "*", "4*");
         table.Add((header == "Properties" ? "Property" : "Parameter"), "Type", "Characteristics", "Description");

         IEnumerable<BplProperty> properties = null;
         if (OutputOptions.Has(BplDocumentationOptions.ShowInherited)) {
            properties = bplClass.Properties;
         } else {
            properties = bplClass.OwnProperties;
         }
         if (bplClass.Operation != null && ConsumerRole != null) {
            properties = properties.Where(_filterPropertiesByConsumer);
         }
         if (OutputOptions.Has(BplDocumentationOptions.SortMembers)) {
            properties = properties.OrderBy(p => p.Name);
         }
         var isGenericResult = bplClass.IsA(typeof(Result<>)) || bplClass.IsA(typeof(ResultSet<>));
         var isGenericValue = bplClass.IsA(typeof(Value<>)) || bplClass.IsA(typeof(ValueSet<>));
         foreach (var property in properties) {
            var name = property.Name.At(0).ToLower() + property.Name.After(0);
            var type = _formatDataType(property);
            var card = _cardinalityConverter.Convert(property);
            Section summary = null;
            if (isGenericResult) {
               summary = _formatDescription(property.ReferencedClass.ToCref());
            } else if (isGenericValue) {
               if (property.PrimitiveType.UnderlyingType == typeof(bool)) {
                  summary = _formatMarkup(null, new XElement("summary", "Indicates success/failure of the operation."));
               } else {
                  summary = _formatDescription(property.PrimitiveType.ToCref());
               }
            } else {
               summary = _formatDescription(property.ToCref());
               if (property.Class != bplClass) {
                  var pclass = property.Class;
                  if (_isEmpty(summary)) {
                     summary = _formatDescription(pclass.GetProperty(property.Name).ToCref());
                  }
                  _append(summary, new Run((_isEmpty(summary) ? "" : " ") + "Inherited from "));
                  _append(summary, _formatHyperlink(pclass.Name, pclass.ToCref()));
                  _append(summary, new Run("."));
               }
            }
            table.Add(name, type, card, summary);
         }

         var section = _createSection();
         if (header.NotEmpty()) {
            section.Blocks.Add(_formatStyledParagraph("@SubTitle", header));
         }
         if (table.RowCount == 1) {
            section.Blocks.Add(new Paragraph(new Run("None")));
         } else {
            section.Blocks.Add(_formatHeaderedTable(table));
         }
         return section;
      }