예제 #1
0
        /// <summary>
        /// StartClass owns EndClass.
        /// </summary>
        public UmlRelation GetOrCreateCompositionRelation(
            bool fromDiagram,
            UmlClass startClass,
            UmlClass endClass,
            string name = null,
            string startMultiplicity = "1",
            string endMultiplicity   = "1"
            )
        {
            var rel = GetRelation <UmlCompositionRelation>(startClass, endClass, name, startMultiplicity,
                                                           endMultiplicity);

            if (rel != null)
            {
                return(rel);
            }

            rel = GetRelation <UmlAssociationRelation>(endClass, startClass, name, startMultiplicity,
                                                       endMultiplicity);
            if (rel != null)
            {
                //
                // Replace association relation by (stronger) composition relation.
                //
                RemoveRelation(rel, false);
            }

            var umlRelation = new UmlCompositionRelation(startClass, endClass, name, startMultiplicity, endMultiplicity);

            AddRelation(umlRelation, fromDiagram);
            return(umlRelation);
        }
예제 #2
0
 public void CreateMethodNodeFromDiagram(UmlClass umlClass, string methodName, out UmlMethodNode umlMethodNode, out UmlMethodLink umlMethodLink)
 {
     umlMethodNode = new UmlMethodNode(methodName);
     umlMethodLink = new UmlMethodLink(umlClass, umlMethodNode);
     AddMethodNode(umlMethodNode);
     AddMethodLink(umlMethodLink);
 }
예제 #3
0
 private IEnumerable <UmlRelation> GetRelations(UmlClass startClass, UmlClass endClass, string name = null)
 {
     return
         (Relations.Where(
              r => r.StartClass == startClass && r.EndClass == endClass && (name == null || r.Label.ToLower() == name.ToLower())
              ));
 }
예제 #4
0
        private void CopyFields(UmlClass umlClass)
        {
            var type = umlClass.TypeDefinition;

            if (type == null)
            {
                return;
            }
            foreach (var field in type.Fields)
            {
                try {
                    var memberType = field.FieldType;

                    string   name;
                    bool     isCollection;
                    UmlClass associatedClass;

                    ProcessType(field, ref memberType, out name, out isCollection, out associatedClass);
                    if (associatedClass != null)
                    {
                        GetOrCreateAssociationRelation(false, umlClass, associatedClass, name, "1", isCollection ? "N" : "1", field);
                    }
                    umlClass.Attributes.Add(new UmlAttribute(field.Name, memberType.Name, GetAccessmodifier(field)));
                } catch (Exception) {
                    continue;
                }
            }
            noAssociationsRetrievedClasses.Remove(umlClass);
        }
예제 #5
0
        private void CopyImplementsInterfaceRelation(UmlClass umlClass, TypeReference interfaceTypeReference)
        {
            var baseClassesAndInterfaces = umlClass.SuperClasses.Concat(umlClass.ImplementedInterfaces);

            if (interfaceTypeReference != null)
            {
                if (
                    baseClassesAndInterfaces.Any(b =>
                                                 b.TypeDefinition.HasInterfaces &&
                                                 b.TypeDefinition.Interfaces.Contains(interfaceTypeReference)
                                                 )
                    )
                {
                    return;
                }
                TypeDefinition interfaceTypeDefinition = interfaceTypeReference.Resolve();
                var            interfaceClass          = interfaceTypeDefinition != null && interfaceTypeDefinition.GetType() != typeof(object)
                                         ? AddOrGetClassFromSolution(interfaceTypeDefinition)
                                         : null;
                if (interfaceClass != null)
                {
                    GetOrCreateImplementsInterfaceRelation(false, umlClass, interfaceClass);
                }
            }
        }
예제 #6
0
 private void CopyImplementsInterfaceRelations(UmlClass umlClass, IEnumerable <TypeReference> interfaceTypeReferences)
 {
     foreach (var interfaceType in interfaceTypeReferences)
     {
         CopyImplementsInterfaceRelation(umlClass, interfaceType);
     }
 }
예제 #7
0
 public void CreateNoteFromDiagram(UmlClass umlClass, string note, out UmlNote umlNote, out UmlNoteLink umlNoteLink)
 {
     umlNote     = new UmlNote(note);
     umlNoteLink = new UmlNoteLink(umlClass, umlNote);
     AddNote(umlNote);
     AddNoteLink(umlNoteLink);
 }
예제 #8
0
        public void RemoveRelations(UmlClass startClass, UmlClass endClass, string name = null)
        {
            var relationsToRemove = GetRelations(startClass, endClass, name);

            foreach (var relation in relationsToRemove)
            {
                RemoveRelation(relation, true);
            }
        }
예제 #9
0
 public UmlClass CreateClassFromDiagram(string name)
 {
     if (Classes.All(c => c.Name != name))
     {
         var umlClass = new UmlClass(name);
         AddClass(umlClass, true);
         return(umlClass);
     }
     return(null);
 }
예제 #10
0
        public List <UmlClass> FindShortestPath(UmlClass class1, UmlClass class2)
        {
            // Dijkstra's algorithm: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

            UmlClass currentClass;
            Dictionary <UmlClass, int> distances = new Dictionary <UmlClass, int>();

            classes.ForEach(c => distances[c] = int.MaxValue);
            distances[class1] = 0;
            List <UmlClass> unvisitedClasses        = Classes.ToList();
            Dictionary <UmlClass, UmlClass> parents = new Dictionary <UmlClass, UmlClass>();

            while (unvisitedClasses.Any() && unvisitedClasses.Contains(class2))
            {
                currentClass = unvisitedClasses.Aggregate((m, c) => distances[m] < distances[c] ? m : c);
                int             currentDistance = distances[currentClass];
                List <UmlClass> neighbours      =
                    currentClass.SuperClasses.Union(currentClass.SubClasses).Union(currentClass.CompositionParentClasses)
                    .Union(currentClass.CompositionChildClasses).Union(currentClass.AssociationParentClasses).Union(
                        currentClass.AssociationChildClasses).ToList();
                //List<UmlClass> neighbours =
                //    currentClass.SubClasses
                //        .Union(currentClass.CompositionChildClasses).Union(
                //            currentClass.AssociationChildClasses).ToList();
                foreach (var neighbour in neighbours)
                {
                    const int distanceToNeighbour = 1;
                    if (neighbour.Name.Contains("Event") || neighbour.Name.Contains("DelegateCommand") || neighbour.Name.Contains("DisplayClass") || neighbour.Name.Contains("`"))
                    {
                        continue;
                    }
                    if (distances[neighbour] > currentDistance + distanceToNeighbour)
                    {
                        distances[neighbour] = currentDistance + distanceToNeighbour;
                        parents[neighbour]   = currentClass;
                    }
                }
                unvisitedClasses.Remove(currentClass);
            }

            // class2 is visited
            // trace back route
            List <UmlClass> route = new List <UmlClass>();

            currentClass = class2;
            route.Add(class2);
            while (distances[currentClass] > 0)
            {
                currentClass = parents[currentClass];
                route.Insert(0, currentClass);
            }

            return(route);
        }
예제 #11
0
        public UmlRelation GetOrCreateImplementsInterfaceRelation(bool fromDiagram, UmlClass startClass, UmlClass endClass)
        {
            UmlRelation rel = GetRelation <UmlImplementsInterfaceRelation>(startClass, endClass);

            if (rel == null)
            {
                rel = new UmlImplementsInterfaceRelation(startClass, endClass);
                AddRelation(rel, fromDiagram);
            }
            return(rel);
        }
 public UmlAssociationRelation(
     UmlClass startClass,
     UmlClass endClass,
     string name = null,
     string startMultiplicity        = "1",
     string endMultiplicity          = "1",
     MemberReference memberReference = null
     ) : base(startClass, endClass, name, startMultiplicity, endMultiplicity)
 {
     MemberReference = memberReference;
 }
예제 #13
0
 public void AddClass(UmlClass umlClass, bool notifyObservers)
 {
     if (!classes.Contains(umlClass))
     {
         AddNode(umlClass);
         classes.Add(umlClass);
         if (notifyObservers)
         {
             OnModified();
         }
     }
 }
예제 #14
0
        public UmlClass GetOrCreateClassFromSolution(TypeDefinition typeDefinition)
        {
            // comparing typeDefinition to typeDefinition gives strange results in which the name is the same ('a') but the fullname can be 'am+ l' ?!
            var umlClass = Classes.FirstOrDefault(c => c.Name == typeDefinition.Name);

            if (umlClass == null)
            {
                umlClass = new UmlClass(typeDefinition, LoadedAssembly);
                AddClass(umlClass, false);
            }
            return(umlClass);
        }
예제 #15
0
 private void CopyInheritanceRelation(UmlClass umlClass, TypeReference baseTypeReference)
 {
     if (baseTypeReference != null)
     {
         TypeDefinition baseTypeDefinition = baseTypeReference.Resolve();
         var            baseClass          = baseTypeDefinition != null && baseTypeDefinition.GetType() != typeof(object)
                             ? AddOrGetClassFromSolution(baseTypeDefinition)
                             : null;
         if (baseClass != null)
         {
             GetOrCreateInheritanceRelation(false, umlClass, baseClass);
         }
     }
 }
예제 #16
0
        private UmlRelation GetRelation <T>(UmlClass startClass, UmlClass endClass, string name = null, string startMultiplicity = "1", string endMultiplicity = "1")
        {
            var rel =
                Relations.FirstOrDefault(
                    r => r is T && r.StartClass == startClass && r.EndClass == endClass && (name == null || r.Label.ToLower() == name.ToLower())
                    );

            if (rel != null)
            {
                if (rel.StartMultiplicity != startMultiplicity || rel.EndMultiplicity != endMultiplicity)
                {
                    throw new ArgumentException("Relation already exists but StartMultiplicity or EndMultiplicity is different");
                }
                return(rel);
            }
            return(null);
        }
예제 #17
0
        // If you want to preserve the generic arguments that can go with a method:
        // https://groups.google.com/forum/#!topic/mono-cecil/yRqhqaaYZnA

        public void FillMethodsFromClass(UmlClass umlClass)
        {
            var type = umlClass.TypeDefinition;

            // NOTE:
            // Fout: we zien nu Operations en Method Associations als verschillende dingen; we moeten nadenken of we de uml conventies van attributes en operations nog
            // wel willen aanhouden. Wat ik interessant vind, is welke fields, properties, methods een class heeft. Misschien moeten we van het hele UML concept afstappen.
            // Ik laat nu nl ook al properties in de view zien, niet volgens UML conventies dus.
            // Maar toch is UML wel heel puur: attributes staan voor state en operations staan voor behavior.
            // We maken het dus zo: een 'UmlClass' bevat alles wat nodig is om allebei af te leiden; de attributes en operations kunnen we dan binnen deze class herleiden.
            //

            if (type != null)
            {
                foreach (var method in type.Methods)
                {
                    if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))
                    {
                        continue;
                    }
                    try {
                        string   name;
                        bool     isCollection;
                        UmlClass associatedClass;
                        var      memberType = method.ReturnType;

                        //ProcessType(method, ref memberType, out name, out isCollection, out associatedClass);
                        //if(associatedClass != null) {
                        //GetOrCreateAssociationRelation(umlClass, associatedClass, name + "()", "1", isCollection ? "N" : "1", method);
                        //} else {
                        umlClass.Operations.Add(new UmlOperation(method.Name, memberType.Name, GetAccessmodifier(method))
                        {
                            Method = method
                        });
                        //}
                    } catch {
                        continue;
                    }
                }
            }
        }
예제 #18
0
        private void CopyProperties(UmlClass umlClass)
        {
            var type = umlClass.TypeDefinition;

            if (type == null)
            {
                // TODO: this happens for example when creating some classes 'a', 'b', 'c', then ClearDiagram and then loading assemblies.
                // c has no type, so: crash
                return;
            }
            foreach (var property in type.Properties)
            {
                try {
                    var memberType = property.PropertyType;

                    string   name;
                    bool     isCollection;
                    UmlClass associatedClass;

                    ProcessType(property, ref memberType, out name, out isCollection, out associatedClass);
                    if (associatedClass != null)
                    {
                        GetOrCreateAssociationRelation(false, umlClass, associatedClass, name, "1", isCollection ? "N" : "1", property);
                    }
                    var getter = property.GetMethod;
                    var setter = property.SetMethod;
                    umlClass.Properties.Add(
                        new UmlProperty(
                            property.Name,
                            memberType.Name,
                            getter != null ? GetAccessmodifier(getter) : AccessModifier.None,
                            setter != null ? GetAccessmodifier(setter) : AccessModifier.None
                            )
                        );
                } catch (Exception) {
                    continue;
                }
            }
            noAssociationsRetrievedClasses.Remove(umlClass);
        }
예제 #19
0
        public void RemoveClass(UmlClass umlClass, bool notifyObservers)
        {
            if (classes.Contains(umlClass))
            {
                RemoveNode(umlClass);
                classes.Remove(umlClass);
                List <UmlRelation> umlRelations =
                    Relations.Where(
                        r =>
                        r.StartClass == umlClass || r.EndClass == umlClass
                        ).ToList();

                foreach (var umlRelation in umlRelations)
                {
                    RemoveRelation(umlRelation, notifyObservers);
                }
                if (notifyObservers)
                {
                    OnModified();
                }
            }
        }
예제 #20
0
        public UmlRelation GetOrCreateAggregationRelation(
            bool fromDiagram,
            UmlClass startClass,
            UmlClass endClass,
            string name = null,
            string startMultiplicity = "1",
            string endMultiplicity   = "1"
            )
        {
            var rel = GetRelation <UmlAggregationRelation>(startClass, endClass, name, startMultiplicity,
                                                           endMultiplicity);

            if (rel != null)
            {
                return(rel);
            }

            var umlRelation = new UmlAggregationRelation(startClass, endClass, name, startMultiplicity, endMultiplicity);

            AddRelation(umlRelation, fromDiagram);
            return(umlRelation);
        }
예제 #21
0
        public UmlRelation GetOrCreateDependenceRelation(
            bool fromDiagram,
            UmlClass startClass,
            UmlClass endClass,
            string name = null,
            string startMultiplicity = "1",
            string endMultiplicity   = "1",
            MemberInfo memberInfo    = null
            )
        {
            var rel = GetRelation <UmlDependenceRelation>(startClass, endClass, name, startMultiplicity,
                                                          endMultiplicity);

            if (rel != null)
            {
                return(rel);
            }

            var umlRelation = new UmlDependenceRelation(startClass, endClass, name, startMultiplicity, endMultiplicity, memberInfo);

            AddRelation(umlRelation, fromDiagram);
            return(umlRelation);
        }
예제 #22
0
 public UmlDependenceRelation(UmlClass startClass, UmlClass endClass, string name = null, string startMultiplicity = "1", string endMultiplicity = "1", MemberInfo memberInfo = null) :
     base(startClass, endClass, name, startMultiplicity, endMultiplicity)
 {
 }
예제 #23
0
        public void RemoveRelation <T>(UmlClass startClass, UmlClass endClass, string name = null)
        {
            var relationToRemove = GetRelation <T>(startClass, endClass, name);

            RemoveRelation(relationToRemove, true);
        }
예제 #24
0
 private void ProcessType(MemberReference memberReference, ref TypeReference typeReference, out string name, out bool isCollection, out UmlClass associatedClass)
 {
     associatedClass = null;
     isCollection    = false;
     name            = null;
     if (!ValueTypes.Contains(typeReference.Name.ToLower()))
     {
         //
         // Yes, we want the associated class in our diagram
         //
         if (typeReference.Name.StartsWith("IList") || typeReference.Name.StartsWith("List`") || typeReference.Name.StartsWith("IEnumerable") || typeReference.Name.StartsWith("ObservableCollection"))
         {
             var genericParameters = ((GenericInstanceType)typeReference).GenericArguments;
             if (genericParameters.Any())
             {
                 typeReference = genericParameters[0];
                 isCollection  = true;
             }
         }
         name = memberReference.Name;
         if (name.EndsWith("BackingField"))
         {
             name = name.Substring(1, name.IndexOf(">", StringComparison.InvariantCulture) - 1);
         }
         associatedClass = AddOrGetClassFromSolution(typeReference.Resolve());
     }
 }