예제 #1
0
        public static void HandleDrop(Store store, string filename)
        {
            if (store == null || filename == null)
            {
                return;
            }

            try
            {
                StatusDisplay.Show($"Reading {filename}");

                AssemblyProcessor assemblyProcessor = new AssemblyProcessor(store);
                TextFileProcessor textFileProcessor = new TextFileProcessor(store);
                textFileProcessor.LoadCache(filename);

                Process(store, filename, assemblyProcessor, textFileProcessor);
            }
            catch (Exception e)
            {
                ErrorDisplay.Show(e.Message);
            }
            finally
            {
                StatusDisplay.Show(string.Empty);
            }
        }
예제 #2
0
        public static IEnumerable <ModelElement> HandleMultiDrop(Store store, IEnumerable <string> filenames)
        {
            List <ModelElement> newElements  = new List <ModelElement>();
            List <string>       filenameList = filenames?.ToList();

            if (store == null || filenameList == null)
            {
                return(newElements);
            }

            try
            {
                StatusDisplay.Show($"Processing {filenameList.Count} files");

                AssemblyProcessor assemblyProcessor = new AssemblyProcessor(store);
                TextFileProcessor textFileProcessor = new TextFileProcessor(store);

                try
                {
                    // may not work. Might not be a text file
                    textFileProcessor.LoadCache(filenameList);
                }
                catch
                {
                    // if not, no big deal. Either it's not a text file, or we'll just process suboptimally
                }

                foreach (string filename in filenameList)
                {
                    newElements.AddRange(Process(store, filename, assemblyProcessor, textFileProcessor));
                }
            }
            catch (Exception e)
            {
                ErrorDisplay.Show(store, e.Message);
            }
            finally
            {
                StatusDisplay.Show("Ready");
            }

            return(newElements);
        }
예제 #3
0
        private static void Process(Store store, string filename, AssemblyProcessor assemblyProcessor, TextFileProcessor textFileProcessor)
        {
            try
            {
                Cursor.Current          = Cursors.WaitCursor;
                ModelRoot.BatchUpdating = true;

                if (IsAssembly(filename))
                {
                    using (Transaction tx = store.TransactionManager.BeginTransaction("Process dropped assembly"))
                    {
                        if (assemblyProcessor.Process(filename))
                        {
                            StatusDisplay.Show("Creating diagram elements. This might take a while...");
                            tx.Commit();

                            ModelDisplay.LayoutDiagram(store.ModelRoot().GetActiveDiagram() as EFModelDiagram);
                        }
                    }
                }
                else
                {
                    using (Transaction tx = store.TransactionManager.BeginTransaction("Process dropped class"))
                    {
                        if (textFileProcessor.Process(filename))
                        {
                            StatusDisplay.Show("Creating diagram elements. This might take a while...");
                            tx.Commit();
                        }
                    }
                }
            }
            finally
            {
                Cursor.Current          = Cursors.Default;
                ModelRoot.BatchUpdating = false;

                StatusDisplay.Show("");
            }
        }
예제 #4
0
        public bool Process(string inputFile, out List <ModelElement> newElements)
        {
            if (string.IsNullOrEmpty(inputFile))
            {
                throw new ArgumentNullException(nameof(inputFile));
            }

            newElements = new List <ModelElement>();

            // did the user drop an intermediate file (one created by one of the parsers)? If so, process it and return the results
            AssemblyProcessor assemblyProcessor = new AssemblyProcessor(Store);

            if (assemblyProcessor.TryProcessIntermediateFile(inputFile, newElements))
            {
                return(true);
            }

            try
            {
                // read the file
                string fileContents = File.ReadAllText(inputFile);

                // parse the contents
                SyntaxTree tree = CSharpSyntaxTree.ParseText(fileContents);

                if (tree.GetRoot() is CompilationUnitSyntax root)
                {
                    List <ClassDeclarationSyntax> classDecls = root.DescendantNodes().OfType <ClassDeclarationSyntax>().Where(classDecl => classDecl.BaseList == null || classDecl.BaseList.Types.FirstOrDefault()?.ToString() != "DbContext").ToList();
                    List <EnumDeclarationSyntax>  enumDecls  = root.DescendantNodes().OfType <EnumDeclarationSyntax>().ToList();

                    if (!classDecls.Any() && !enumDecls.Any())
                    {
                        WarningDisplay.Show($"Couldn't find any classes or enums to add to the model in {inputFile}");

                        return(false);
                    }

                    // keep this order: enums, classes, class properties

                    newElements.AddRange(enumDecls.Select(d => ProcessEnum(d)).Where(e => e != null));

                    List <ModelClass>             processedClasses = new List <ModelClass>();
                    List <ClassDeclarationSyntax> badClasses       = new List <ClassDeclarationSyntax>();

                    foreach (ClassDeclarationSyntax classDecl in classDecls)
                    {
                        ModelClass modelClass = ProcessClass(classDecl, newElements);

                        if (modelClass == null)
                        {
                            badClasses.Add(classDecl);
                        }
                        else
                        {
                            processedClasses.Add(modelClass);
                        }
                    }

                    // process last so all classes and enums are already in the model
                    foreach (ClassDeclarationSyntax classDecl in classDecls.Except(badClasses))
                    {
                        ProcessProperties(classDecl);
                    }

                    // now that all the properties are in, go through the classes again and ensure identities are present based on convention
                    // ReSharper disable once LoopCanBePartlyConvertedToQuery
                    foreach (ModelClass modelClass in processedClasses.Where(c => !c.AllIdentityAttributes.Any()))
                    {
                        // no identity attribute. Only look in current class for attributes that could be identity by convention
                        List <ModelAttribute> identitiesByConvention = modelClass.Attributes.Where(a => a.Name == "Id" || a.Name == $"{modelClass.Name}Id").ToList();

                        // if both 'Id' and '[ClassName]Id' are present, don't do anything since we don't know which to make the identity
                        if (identitiesByConvention.Count == 1)
                        {
                            using (Transaction transaction = Store.TransactionManager.BeginTransaction("Add identity"))
                            {
                                identitiesByConvention[0].IsIdentity = true;
                                transaction.Commit();
                            }
                        }
                    }
                }
            }
            catch
            {
                ErrorDisplay.Show(Store, "Error interpreting " + inputFile);

                return(false);
            }

            return(true);
        }
예제 #5
0
        private static IEnumerable <ModelElement> Process(Store store, string filename, AssemblyProcessor assemblyProcessor, TextFileProcessor textFileProcessor)
        {
            List <ModelElement> newElements;
            Cursor prev = Cursor.Current;

            try
            {
                Cursor.Current          = Cursors.WaitCursor;
                ModelRoot.BatchUpdating = true;

                using (Transaction tx = store.TransactionManager.BeginTransaction("Process drop"))
                {
                    bool processingResult = IsAssembly(filename)
                                          ? assemblyProcessor.Process(filename, out newElements)
                                          : textFileProcessor.Process(filename, out newElements);

                    if (processingResult)
                    {
                        StatusDisplay.Show("Creating diagram elements. This might take a while...");
                        tx.Commit();
                    }
                    else
                    {
                        newElements = new List <ModelElement>();
                    }
                }
            }
            finally
            {
                Cursor.Current          = prev;
                ModelRoot.BatchUpdating = false;

                StatusDisplay.Show("Ready");
            }

            return(newElements);
        }