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; }