public Task WriteAsync(EntityDiagram diagram, Stream stream) { return(WriteInternal(diagram, stream)); }
public Task WriteAsync(EntityDiagram diagram, TextWriter writer) { writer.Write(@"@startuml "); writer.WriteLine(diagram.Entities.FirstOrDefault(e => !string.IsNullOrEmpty(e.Package))?.Package ?? "Entities"); writer.WriteLine(); foreach (var skinParam in SkipParams) { writer.Write("skinparam "); writer.Write(skinParam.Key); writer.Write(" "); writer.WriteLine(skinParam.Value); } writer.WriteLine(); foreach (var package in diagram.Entities .GroupBy(e => e.Package ?? "") .OrderBy(p => string.IsNullOrEmpty(p.Key) ? 1 : 0)) { if (!string.IsNullOrEmpty(package.Key)) { writer.Write("package \""); writer.Write(package.Key); writer.WriteLine("\" <<Rectangle>> {"); } foreach (var entity in package) { writer.Write(entity.Type.ToString().ToLowerInvariant()); writer.Write(" \""); var parts = entity.Label.Split('\n'); parts[0] = "**" + parts[0] + "**"; writer.Write(string.Join("\\n", parts)); writer.Write("\" as "); writer.Write(entity.Id); if (!string.IsNullOrEmpty(entity.Stereotype)) { writer.Write(" << "); writer.Write(entity.Stereotype); writer.Write(" >>"); } writer.WriteLine(); writer.WriteLine("{"); foreach (var attribute in entity.Attributes) { switch (attribute.Visiblity) { case AttributeVisibility.Package: writer.Write(" ~"); break; case AttributeVisibility.Private: writer.Write(" -"); break; case AttributeVisibility.Protected: writer.Write(" #"); break; case AttributeVisibility.Public: writer.Write(" +"); break; default: writer.Write(" "); break; } writer.Write(attribute.Name); if (!string.IsNullOrEmpty(attribute.DataType)) { writer.Write(" : "); writer.Write(attribute.DataType); } writer.WriteLine(); } writer.WriteLine("}"); if (!string.IsNullOrEmpty(entity.Note)) { writer.WriteLine("note right"); writer.WriteLine(entity.Note); writer.WriteLine("end note"); } } if (!string.IsNullOrEmpty(package.Key)) { writer.WriteLine("}"); } } foreach (var association in diagram.Associations) { writer.Write(association.Source.Entity.Id); writer.Write(AssociationEndLabel(association.Source)); writer.Write(" "); writer.Write(AssociationSymbol(association.Source.Type, true)); writer.Write(association.Dashed ? ".." : "--"); writer.Write(AssociationSymbol(association.Related.Type, false)); writer.Write(AssociationEndLabel(association.Related)); writer.Write(" "); writer.Write(association.Related.Entity.Id); if (!string.IsNullOrEmpty(association.Label)) { writer.Write(" : "); writer.Write(association.Label); } writer.WriteLine(); } writer.WriteLine("@enduml"); writer.Flush(); return(Task.FromResult(true)); }
public static EntityDiagram FromTypes(IEnumerable <ItemType> itemTypes, string packageName) { var result = new EntityDiagram(); var allNames = new HashSet <string>(); itemTypes = itemTypes.Where(i => !i.IsUiOnly); var entities = itemTypes.ToDictionary(i => i.Name, i => { var entity = new Entity() { Id = i.Name.Replace(' ', '_'), Label = i.Name }; var label = i.Label ?? i.TabLabel; if (!string.IsNullOrEmpty(label)) { entity.Label += $"\n({label})"; } entity.Attributes.AddRange(i.Properties.Values .Where(p => p.Applicable && !p.Core) .OrderBy(p => p.Name) .Select(p => new EntityAttribute() { Name = p.Name, DataType = p.TypeDisplay() })); entity.Package = packageName; if (i.IsPolymorphic) { entity.Stereotype = "polymorphic"; entity.Type = EntityType.Abstract; } else if (i.IsFederated) { entity.Stereotype = "federated"; } else if (i.IsRelationship) { entity.Stereotype = "relationship"; } if (i.ClassPaths.Any()) { var builder = new StringBuilder("Classes\r\n"); BuildClassificationNote(i.ClassStructure, 0, builder); entity.Note = builder.ToString().Trim(); } allNames.Add(i.SourceTypeName ?? ""); allNames.Add(i.RelatedTypeName ?? ""); allNames.UnionWith(i.Morphae); return(entity); }); foreach (var name in allNames .Where(n => !string.IsNullOrEmpty(n) && !entities.ContainsKey(n))) { entities[name] = new Entity() { Id = name.Replace(' ', '_'), Label = name }; } result.Entities.AddRange(entities.Values); foreach (var itemType in itemTypes) { var source = entities[itemType.Name]; foreach (var prop in itemType.Properties.Values .Where(p => p.Type == PropertyType.item && p.Restrictions.Count > 0 && (p.Name == "related_id" || p.Name == "source_id"))) { if (entities.TryGetValue(prop.Restrictions[0], out var target)) { var relEnd = new AssociationEnd() { Entity = source, Multiplicity = int.MaxValue, Type = AssociationType.Composition }; var nonRelEnd = new AssociationEnd() { Entity = target, Multiplicity = 1, }; result.Associations.Add(prop.Name == "source_id" ? new EntityAssociation() { Source = nonRelEnd, Related = relEnd, Label = prop.Name } : new EntityAssociation() { Source = relEnd, Related = nonRelEnd, Label = prop.Name }); } } foreach (var morphae in itemType.Morphae) { if (entities.TryGetValue(morphae, out var target)) { result.Associations.Add(new EntityAssociation() { Source = new AssociationEnd() { Entity = source, Type = AssociationType.Inheritance }, Related = new AssociationEnd() { Entity = target, }, Label = "Implements" }); } } } return(result); }
public async Task WriteAsync(PackageMetadataProvider metadata, Stream stream) { var entityDiagram = EntityDiagram.FromTypes(metadata.ItemTypes, metadata.Title); ImageWriter = ImageWriter ?? new HttpImageWriter(); ImageWriter.Format = Format.ToString().ToLowerInvariant(); ImageWriter.Writer = ImageWriter.Writer ?? new PlantUmlWriter(); if (Output == DocumentOutput.Markdown) { using (var writer = new StreamWriter(stream)) { writer.WriteLine("# Data Model"); writer.WriteLine(); await WriteDiagramMarkdown(entityDiagram, writer); writer.WriteLine(); var mdWriter = new MarkdownVisitor(writer); var itemTypes = OrderTypes(metadata.ItemTypes.Where(i => !i.IsUiOnly).OrderBy(i => i.Name)).ToList(); foreach (var itemType in itemTypes) { mdWriter.Visit(Document.FromItemType(itemType, new DocumentOptions() { IncludeCrossReferenceLinks = false, IncludeCoreProperties = false }, metadata)); } writer.WriteLine(); foreach (var group in metadata.Diagrams.GroupBy(d => d.Type)) { writer.WriteLine("# " + group.Key); writer.WriteLine(); foreach (var diagram in group) { var name = diagram.Name; if (!string.IsNullOrEmpty(diagram.Label) && !string.Equals(diagram.Label, diagram.Name, StringComparison.OrdinalIgnoreCase)) { name += $" ({diagram.Label})"; } writer.WriteLine("## " + name); writer.WriteLine(); await WriteDiagramMarkdown(diagram, writer); writer.WriteLine(); } } } } else { if (Format == DiagramFormat.PlantUml) { await entityDiagram.WriteAsync(ImageWriter.Writer, new StreamWriter(stream)); } else { ImageWriter.Format = Format.ToString().ToLowerInvariant(); await entityDiagram.WriteAsync(ImageWriter, stream); } } }