Exemple #1
0
        public UMLTree(UMLClass diagram)
        {
            this.diagram = diagram;
            Graph = new Dictionary<string,List<string>>();
            Mapping = new Dictionary<string,Node>();

            foreach (var classnode in diagram.ClassNodes){
                if(!Graph.ContainsKey(classnode.Name)){
                    Graph.Add(classnode.Name, new List<String>());
                    Mapping.Add(classnode.Name, classnode);
                }
            }

            foreach (var interfacenode in diagram.InterfaceNodes){
                if(!Graph.ContainsKey(interfacenode.Name)){
                    Graph.Add(interfacenode.Name, new List<String>());
                    Mapping.Add(interfacenode.Name, interfacenode);
                }
            }

            foreach (var structnode in diagram.StructNodes){
                if (!Graph.ContainsKey (structnode.Name)) {
                    Graph.Add(structnode.Name, new List<String>());
                    Mapping.Add(structnode.Name, structnode);
                }
            }

            foreach (var enumnode in diagram.EnumNodes){
                if (!Graph.ContainsKey (enumnode.Name)) {
                    Graph.Add(enumnode.Name, new List<String>());
                    Mapping.Add(enumnode.Name, enumnode);
                }
            }
        }
        public ClassDesigner(UMLClass cls)
        {
            ContentName = GettextCatalog.GetString ("Class Diagram");
            IsViewOnly = true;
            mhdEditor = new MonoHotDraw.SteticComponent();
            mhdEditor.ShowAll();

            ILayout algorithm = new TreeLayout();
            foreach(var figure in algorithm.GetFigures(cls))
            {
                mhdEditor.View.Drawing.Add(figure);
            }
        }
        /// <summary>
        /// Returns all the figures to be drawn
        /// </summary>
        /// <returns>The figures.</returns>
        /// <param name="cls">Project details.</param>
        public IEnumerable<IFigure> GetFigures(UMLClass cls)
        {
            // We build trees with the input
            Roots = GetTreeRoots(cls);

            #region Class Blocks
            double x = X_START;
            double y = Y_START;
            // For each tree, we perform a level order traversal
            // and draw the tree in that order. This, will make sure
            // that links don't overlap each other.
            foreach(var root in Roots)
            {
                if(root.children.Count == 0){
                    //figures.Add(new ClassFigure((ClassNode)root.Node));
                    Singles.Add(new ClassFigure((ClassNode)root.Node));
                    continue;
                }
                Queue<TreeNode> queue1 = new Queue<TreeNode>();
                Queue<TreeNode> queue2 = new Queue<TreeNode>();
                queue1.Enqueue(root);
                int level = 0;
                x = X_START;
                var root_figure = new ClassFigure((ClassNode)root.Node);
                root_figure.MoveTo(x,y);
                figures.Add(root_figure);
                while(queue1.Count != 0 || queue2.Count != 0){
                    while(queue1.Count !=0){
                        var parent = queue1.Dequeue();
                        foreach(var child in parent.children){
                            queue2.Enqueue(child);
                        }
                    }
                    level = level + 1;

                    x = X_START;
                    y+= Y_INCREMENT;
                    foreach(var node in queue2){
                        var figure = new ClassFigure((ClassNode)node.Node);
                        figure.MoveTo(x,y);
                        x += figure.DisplayBox.Width + 50.0;
                        figures.Add(figure);
                        //connections.Add(new InheritanceConnectionFigure(figure, node.P
                    }
                    if(queue2.Count == 0) continue;
                    while(queue2.Count !=0){
                        var parent = queue2.Dequeue();
                        foreach(var child in parent.children){
                            queue1.Enqueue(child);
                        }
                    }
                    level = level + 1;
                    x = X_START;
                    y+= Y_INCREMENT;
                    foreach(var node in queue1){
                        var figure = new ClassFigure((ClassNode)node.Node);
                        figure.MoveTo(x,y);
                        x += figure.DisplayBox.Width + 50.0;
                        figures.Add(figure);
                    }

                }
            }
            #endregion Class Blocks

            #region Links
            foreach(var node in cls.ClassNodes){
                // Add all inheritance links
                TypeFigure subclass = GetFigure(node.Namespace);
                foreach(var link in node.Links){
                    TypeFigure superclass = GetFigure(link);
                    if (subclass != null && superclass != null) {
                        InheritanceConnectionFigure connection = new InheritanceConnectionFigure(subclass, superclass);
                        yield return connection;
                    }
                }
                if(node.Implementations.Count ==0) continue;

                // Handle implementations
                string imps = "";
                //Position the text to the center of the box
                string space_string = "";
                int len = subclass.Namespace.Length;

                foreach(var implementation in node.Implementations)
                {
                    for(int i =0;i<(len - implementation.Length) /2;i++) space_string +=" ";

                    imps= imps + space_string + implementation + space_string;
                    imps+="\n";
                }
                SimpleTextFigure interf = new SimpleTextFigure(imps);
                figureToInterfaces.Add(subclass.Namespace,interf);
                InheritanceConnectionFigure connex = new InheritanceConnectionFigure(subclass, interf);
                yield return connex;

            }
            //Positioning the interface names on top of the class figures
            foreach(var item in figures){
                if(figureToInterfaces.ContainsKey(item.Namespace)){
                    var simple = figureToInterfaces[item.Namespace];
                    simple.MoveTo(item.DisplayBox.X,item.DisplayBox.Y-50);
                    yield return simple;
                }
                yield return item;
            }
            #endregion Links

            #region Single Nodes
            // Draw single nodes in a row
            x = X_START;
            foreach(var item in Singles){
                item.MoveTo(x,y);
                x += item.DisplayBox.Width + SINGLES_GAP;
                if(x>PAGE_WIDTH_LIMIT){
                    x = X_START;
                    y+= Y_INCREMENT;
                }
                if(figureToInterfaces.ContainsKey(item.Namespace)){
                    var simple = figureToInterfaces[item.Namespace];
                    simple.MoveTo(item.DisplayBox.X,item.DisplayBox.Y-50);
                    yield return simple;
                }
                yield return item;
            }

            // Next, all structures, enum and interfaces are drawn.
            foreach(var node in cls.StructNodes){
                var item = new StructFigure(node);
                item.MoveTo(x,y);
                x += item.DisplayBox.Width + SINGLES_GAP;
                if(x>PAGE_WIDTH_LIMIT){
                    x = X_START;
                    y+= Y_INCREMENT;
                }
                yield return item;
            }
            foreach(var node in cls.EnumNodes){
                var item = new EnumFigure(node);
                item.MoveTo(x,y);
                x += item.DisplayBox.Width + SINGLES_GAP;
                if(x> PAGE_WIDTH_LIMIT){
                    x = X_START;
                    y+= Y_INCREMENT;
                }
                yield return item;
            }
            foreach(var node in cls.InterfaceNodes){
                var item = new InterfaceFigure(node);
                item.MoveTo(x,y);
                x += item.DisplayBox.Width + SINGLES_GAP;
                if(x>PAGE_WIDTH_LIMIT){
                    x = X_START;
                    y+= Y_INCREMENT;
                }
                yield return item;
            }
            #endregion Single Nodes
        }
        /// <summary>
        /// Gets the tree roots.
        /// </summary>
        /// <returns>List of roots</returns>
        /// <param name="cls">Project details</param>
        private List<TreeNode> GetTreeRoots(UMLClass cls)
        {
            // Map every class node.
            // Namespace - Treenode
            foreach(var cnode in cls.ClassNodes){
                TreeNode tn = new TreeNode(cnode.Namespace);
                tn.Node = cnode;
                TreeNodes.Add(tn);
                if(!map.ContainsKey(tn.Name))
                    map.Add(tn.Name,tn);
            }

            //Create all parent child links
            foreach(var cnode in cls.ClassNodes)
            {
                foreach(var parent in cnode.Links)
                {
                    var parentnode = GetTreeNode(parent);
                    var childnode = GetTreeNode(cnode.Namespace);

                    if(parentnode == null){
                        //If inherits class outside project
                        continue;
                    }
                    parentnode.AddChild(childnode);
                    childnode.Parent = parentnode;
                }
            }

            //At this point, we have a forest. Every tree in the
            //forest wil be drawn separately

            List<TreeNode> Roots = new List<TreeNode>();
            // Add all roots to a list
            foreach(TreeNode tn in TreeNodes)
            {
                var temp = tn;
                while(temp.Parent !=null){
                    temp = temp.Parent;
                }
                if(!Roots.Contains(temp))
                {
                    Roots.Add(temp);
                }
            }
            return Roots;
        }
        public IEnumerable<IFigure> GetFigures(UMLClass cls)
        {
            // Add all entities
            foreach(var classnode in cls.ClassNodes){
                figures.Add(new ClassFigure(classnode));
                AllNodes.Add(classnode);
                //NodeMapping.Add(classnode.Namespace,classnode);
            }
            foreach(var interfacenode in cls.InterfaceNodes){
                figures.Add(new InterfaceFigure(interfacenode));
                AllNodes.Add(interfacenode);
                //NodeMapping.Add(interfacenode.Namespace,interfacenode);
            }
            foreach(var structnode in cls.StructNodes){
                figures.Add(new StructFigure(structnode));
                AllNodes.Add(structnode);
                //NodeMapping.Add(structnode.Namespace,structnode);
            }
            foreach(var enumnode in cls.EnumNodes){
                figures.Add(new EnumFigure(enumnode));
                AllNodes.Add(enumnode);
                //NodeMapping.Add(enumnode.Namespace,enumnode);
            }

            // Iterate over links of all entities and draw links.
            foreach (var node in AllNodes) {
                TypeFigure subclass = GetFigure(node.Namespace);
                foreach(var link in node.Links){
                    TypeFigure superclass = GetFigure(link);
                    if (subclass != null && superclass != null) {
                        InheritanceConnectionFigure connection = new InheritanceConnectionFigure(subclass, superclass);
                        //connection.EndHandle.Owner.
                        yield return connection;
                    }
                }
                if(node.Implementations.Count ==0) continue;
                string imps = "";
                foreach(var implementation in node.Implementations)
                {
                    imps+=implementation;
                    imps+="\n";
                }
                SimpleTextFigure interf = new SimpleTextFigure(imps);
                figureToInterfaces.Add(subclass.Namespace,interf);
                implementations.Add(interf);
                InheritanceConnectionFigure connex = new InheritanceConnectionFigure(subclass, interf);
                yield return connex;

            }
            double x = 50.0;
            double y = 50.0;

            foreach (TypeFigure figure in figures)  {
                figure.MoveTo(x, y);
                if(figureToInterfaces.ContainsKey(figure.Namespace)){
                    var simple = figureToInterfaces[figure.Namespace];
                    simple.MoveTo(x,y-50);
                    yield return simple;
                }
                yield return figure;
                x += figure.DisplayBox.Width + 50.0;
                if (x > 1000.0) {
                    x = 50.0;
                    y += figure.DisplayBox.Height + 100.0;

                }
            }
            //foreach(var figure in implementations)
            //{
            //    figure.MoveTo(x,y);
            //    yield return figure;
            //    x += figure.DisplayBox.Width + 50.0;
            //    if (x > 1000.0) {
            //        x = 50.0;
            //        y += figure.DisplayBox.Height + 100.0;
            //    }
            //}
        }
        public static UMLClass ParseFiles(Compilation compilation)
        {
            foreach (var item in compilation.GetDiagnostics())
            {
                if (item.Severity == DiagnosticSeverity.Error)
                {
                    Console.WriteLine("Code has compile time errors. Kindly fix them");
                }
            }

            var syntaxTrees = compilation.SyntaxTrees;
            foreach(var syntaxTree in syntaxTrees)
            {
                models.Add(compilation.GetSemanticModel(syntaxTree));
            }

            UMLClass uml = new UMLClass();
            // Each file in the project
            foreach (var st in syntaxTrees)
            {
                // Get semantic model for this file for getting info like class namespaces
                model = compilation.GetSemanticModel(st);

                //For each class in file
                var AllClasses = st.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>();
                foreach (var EachClass in AllClasses)
                {
                    ClassNode c = GetClassNode(EachClass);
                    c.Namespace = model.GetDeclaredSymbol(EachClass).ToString();
                    c.FilePath = st.FilePath;
                    uml.ClassNodes.Add(c);
                }

                //For each struct in file
                var AllStructs = st.GetRoot().DescendantNodes().OfType<StructDeclarationSyntax>();
                foreach (var EachStruct in AllStructs)
                {
                    StructNode snode = GetStructNode(EachStruct);
                    snode.Namespace = model.GetDeclaredSymbol(EachStruct).ToString();
                    snode.FilePath = st.FilePath;
                    uml.StructNodes.Add(snode);
                }

                // For reach interface in file
                var AllInterfaces = st.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>();
                foreach (var EachInterface in AllInterfaces)
                {
                    InterfaceNode inf = GetInterfaceNode(EachInterface);
                    inf.Namespace = model.GetDeclaredSymbol(EachInterface).ToString();
                    inf.FilePath = st.FilePath;
                    uml.InterfaceNodes.Add(inf);

                }

                //For each enum in file
                var AllEnums = st.GetRoot().DescendantNodes().OfType<EnumDeclarationSyntax>();
                foreach (var EachEnum in AllEnums)
                {
                    EnumNode enode = GetEnumNode(EachEnum);
                    enode.Namespace = model.GetDeclaredSymbol(EachEnum).ToString();
                    enode.FilePath = st.FilePath;
                    uml.EnumNodes.Add(enode);
                }
            }
            return uml;
        }