public Task WriteAsync(EntityDiagram diagram, Stream stream)
 {
     return(WriteInternal(diagram, stream));
 }
Exemple #2
0
        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));
        }
Exemple #3
0
        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);
                }
            }
        }