Ejemplo n.º 1
0
        private Node AddOrGetClassNode(Type type, ICollection <Type> types)
        {
            //if (type.IsValueType || type.Name == "String" || !types.Contains(type)) return null;
            if (type.IsValueType || type.Name == "String")
            {
                return(null);
            }

            var baseType = type.BaseType;

            if (!generatedNodes.ContainsKey(type))
            {
                //
                // Add a node if it doesn't exist yet and cache it
                //
                var node = AddNode(type) as UmlClass;
                Debug.Assert(node != null);
                generatedNodes[type] = node;

                PropertyInfo[] fields = type.GetProperties();
                int            i      = 0;
                foreach (var field in fields)
                {
                    Type fieldType;
                    try {
                        fieldType = field.PropertyType;
                    } catch (Exception) {
                        continue;
                    }
                    if (i < 1 && !fieldType.IsValueType && fieldType.Name != "String")  //types.Contains(field.PropertyType)) {
                    //
                    // Yes, we want the comprised node in our diagram
                    //
                    {
                        Node comprisedNode = AddOrGetClassNode(fieldType, types);
                        if (comprisedNode != null)
                        {
                            comprisedNode.Pos = node.Pos;
                            TranslateChildNodes(comprisedNode, new Vector3D(50, 0, 0));
                            var link = new UmlCompositionRelation("135");
                            link.EndNode   = node; // node2 = parent, node1 = child
                            link.StartNode = comprisedNode;
                            node.Links.Add(link);
                            comprisedNode.Links.Add(link);
                            Links.Add(link);
                            i++;
                        }
                    }
                }
                //
                // Now, check the base types of this type
                //
                var parentNode = baseType != null && baseType != typeof(object) ? AddOrGetClassNode(baseType, types) : null;
                if (parentNode != null)
                {
                    var link = new UmlInheritanceRelation("90");
                    link.StartNode = node;
                    link.EndNode   = parentNode;
                    parentNode.Pos = node.Pos + new Vector3D(0, -50, 0);
                    node.Links.Add(link);
                    parentNode.Links.Add(link);
                    Links.Add(link);
                }
                return(node);
            }
            return(generatedNodes[type]);
        }
Ejemplo n.º 2
0
        private void OnCreatorTextChanged(string newCreatorText)
        {
            UmlClass umlClassBeforeOperator = null;
            Link     link = null;

            if (string.IsNullOrWhiteSpace(newCreatorText))
            {
                return;
            }

            if (newCreatorText.EndsWith("\r\n"))
            {
                currentCreatorAction = CreatorAction.None;
                if (totalStringBuilder.Length > 0)
                {
                    totalStringBuilder.Append(" ");
                }
                totalStringBuilder.Append(newCreatorText.Substring(0, newCreatorText.Length - 2));

                //Commit creator text
                string[] tokens        = newCreatorText.Split(new[] { ' ', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                bool     endsWithDot   = false;
                bool     endsWithColon = false;
                bool     endsWithN     = false;
                bool     not           = false;
                foreach (string token in tokens)
                {
                    string token2 = token.Trim();
                    if (token.EndsWith("."))
                    {
                        endsWithDot = true;
                        token2      = token2.Substring(0, token.Length - 1);
                    }
                    if (token.EndsWith(":"))
                    {
                        endsWithColon = true;
                        token2        = token2.Substring(0, token.Length - 1);
                    }
                    if (token.EndsWith("N"))
                    {
                        endsWithN = true;
                        token2    = token2.Substring(0, token.Length - 1);
                    }
                    switch (token2.ToLower())
                    {
                    case "reset":
                        totalStringBuilder.Clear();
                        Diagram.Reset();
                        CreatorText = null;
                        return;

                    case "resetclass":
                        currentCreatorAction = CreatorAction.ResettingClass;
                        break;

                    case "not":
                        not = true;
                        break;

                    case "delete":
                        currentCreatorAction = CreatorAction.DeletingClass;
                        break;

                    case "rename":
                        currentCreatorAction = CreatorAction.Renaming;
                        break;

                    case "to":
                        if (currentCreatorAction == CreatorAction.Renaming)
                        {
                            currentCreatorAction = CreatorAction.RenamingTo;
                        }
                        break;

                    case "is":
                        link = new UmlInheritanceRelation(InheritanceRelationPreferredAngles);
                        break;

                    case "implements":
                        link = new UmlImplementsInterfaceRelation(InheritanceRelationPreferredAngles);
                        break;

                    case "dependson":
                    case "uses":
                        link = new UmlDependsOnRelation(AssociationRelationPreferredAngles);
                        break;

                    case "owns":
                    case "creates":
                        link = new UmlCompositionRelation(CompositionRelationPreferredAngles, endsWithN ? "N" : "1");
                        break;

                    case "contains":
                        link = new UmlAggregationRelation(AggregationRelationPreferredAngles, endsWithN ? "N" : "1");
                        break;

                    case "has":
                        link = new UmlAssociationRelation(AssociationRelationPreferredAngles);
                        break;

                    default:
                        if (link == null)
                        {
                            if (currentCreatorAction == CreatorAction.DeletingClass)
                            {
                                umlClassBeforeOperator = GetOrCreateUmlClass(token2);
                                Diagram.DeleteNode(umlClassBeforeOperator);
                                umlClassBeforeOperator = null;
                                currentCreatorAction   = CreatorAction.None;
                                break;
                            }
                            if (currentCreatorAction == CreatorAction.RenamingTo && umlClassBeforeOperator != null)
                            {
                                umlClassBeforeOperator.Name = token2;
                                currentCreatorAction        = CreatorAction.None;
                                break;
                            }
                            if (currentCreatorAction == CreatorAction.ResettingClass)
                            {
                                umlClassBeforeOperator = GetOrCreateUmlClass(token2);
                                umlClassBeforeOperator.BackgroundBrush = null;
                                umlClassBeforeOperator = null;
                                currentCreatorAction   = CreatorAction.None;
                                break;
                            }
                            if (currentCreatorAction == CreatorAction.None && endsWithColon)
                            {
                                // Current token is a shortcut for 'has <action>:subject' -> '<action>: subject'
                                link = new UmlAssociationRelation(AssociationRelationPreferredAngles);
                                break;
                            }
                            umlClassBeforeOperator = GetOrCreateUmlClass(token2);
                        }
                        else
                        {
                            string name         = null;
                            int    indexOfColon = token2.IndexOf(":");  // ':' indicates value type. Optional are access modifier and type
                            if (indexOfColon > -1)
                            {
                                // Value type
                                AccessModifier am          = AccessModifier.None;
                                int            indexOfName = 0;
                                if (token2.StartsWith("-"))
                                {
                                    am = AccessModifier.Private; indexOfName = 1;
                                }
                                if (token2.StartsWith("#"))
                                {
                                    am = AccessModifier.Protected; indexOfName = 1;
                                }
                                if (token2.StartsWith("$#"))
                                {
                                    am = AccessModifier.ProtectedInternal; indexOfName = 2;
                                }
                                if (token2.StartsWith("$"))
                                {
                                    am = AccessModifier.Internal; indexOfName = 1;
                                }
                                if (token2.StartsWith("+"))
                                {
                                    am = AccessModifier.Public; indexOfName = 1;
                                }

                                name = token2.Substring(indexOfName, indexOfColon - indexOfName);
                                if (indexOfColon < token2.Length - 1)
                                {
                                    // colon is not the last character, so there is a type specified
                                    string type      = token2.Substring(indexOfColon + 1);
                                    var    lowerType = type.ToLower();
                                    if (!valueTypes.Contains(lowerType) && !name.EndsWith("()"))
                                    {
                                        // Reference type and no operation
                                        token2     = type;
                                        link.Label = name;
                                    }
                                    else
                                    {
                                        // value type
                                        bool isOperation = name.EndsWith("()");
                                        if (isOperation)
                                        {
                                            name = name.Substring(0, name.Length - 2);
                                            umlClassBeforeOperator.Operations.Add(new UmlOperation(name, type, am));
                                        }
                                        else
                                        {
                                            umlClassBeforeOperator.Attributes.Add(new UmlAttribute(name, type, am));
                                        }
                                        link = null;
                                        // TODO: not
                                        break;
                                    }
                                }
                                else
                                {
                                    // value type
                                    bool isOperation = name.EndsWith("()");
                                    if (isOperation)
                                    {
                                        name = name.Substring(0, name.Length - 2);
                                        umlClassBeforeOperator.Operations.Add(new UmlOperation(name, null, am));
                                    }
                                    else
                                    {
                                        umlClassBeforeOperator.Attributes.Add(new UmlAttribute(name, null, am));
                                    }
                                    link = null;
                                    // TODO: not
                                    break;
                                }
                            }
                            var umlClassAfterOperator = GetOrCreateUmlClass(token2);
                            if (umlClassBeforeOperator != null && umlClassAfterOperator != null)
                            {
                                if (not)
                                {
                                    List <Link> linksToDelete = new List <Link>();
                                    foreach (var linkToDelete in umlClassBeforeOperator.Links)
                                    {
                                        if (
                                            linkToDelete.GetType() == link.GetType() &&
                                            (
                                                (linkToDelete is UmlInheritanceRelation || linkToDelete is UmlAssociationRelation) &&
                                                linkToDelete.StartNode == umlClassBeforeOperator && linkToDelete.EndNode == umlClassAfterOperator ||
                                                linkToDelete.StartNode == umlClassAfterOperator && linkToDelete.EndNode == umlClassBeforeOperator
                                            )
                                            )
                                        {
                                            linksToDelete.Add(linkToDelete);
                                        }
                                    }
                                    foreach (var linkToDelete in linksToDelete)
                                    {
                                        Diagram.DeleteLink(linkToDelete);
                                    }
                                }
                                else
                                {
                                    if (link is UmlInheritanceRelation || link is UmlAssociationRelation)
                                    {
                                        // StartNode <link> EndNode
                                        link.StartNode = umlClassBeforeOperator;
                                        link.EndNode   = umlClassAfterOperator;
                                    }
                                    else
                                    {
                                        link.EndNode   = umlClassBeforeOperator;
                                        link.StartNode = umlClassAfterOperator;
                                    }
                                    umlClassBeforeOperator.Links.Add(link);
                                    umlClassAfterOperator.Links.Add(link);
                                    Diagram.Links.Add(link);
                                }
                                link = null;
                                not  = false;
                                if (endsWithDot)
                                {
                                    umlClassBeforeOperator = umlClassAfterOperator;
                                }
                            }
                        }
                        break;
                    }
                    if (endsWithColon && link != null)
                    {
                        link.Label = token2.Replace("_", " ");
                    }
                    endsWithColon = false;
                    endsWithDot   = false;
                    endsWithN     = false;
                }
                CreatorText = "";
            }
        }