Exemple #1
0
        /** This method is used by all code generators to create new output
         *  files. If the outputDir set by -o is not present it will be created.
         *  The final filename is sensitive to the output directory and
         *  the directory where the grammar file was found.  If -o is /tmp
         *  and the original grammar file was foo/t.g4 then output files
         *  go in /tmp/foo.
         *
         *  The output dir -o spec takes precedence if it's absolute.
         *  E.g., if the grammar file dir is absolute the output dir is given
         *  precedence. "-o /tmp /usr/lib/t.g4" results in "/tmp/T.java" as
         *  output (assuming t.g4 holds T.java).
         *
         *  If no -o is specified, then just write to the directory where the
         *  grammar file was found.
         *
         *  If outputDirectory==null then write a String.
         */
        public virtual TextWriter GetOutputFileWriter(Grammar g, string fileName)
        {
            if (outputDirectory == null)
            {
                return(new StringWriter());
            }

            // output directory is a function of where the grammar file lives
            // for subdir/T.g4, you get subdir here.  Well, depends on -o etc...
            string outputDir  = GetOutputDirectory(g.fileName);
            string outputFile = Path.Combine(outputDir, fileName);

            ConsoleOut.WriteLine($"Generating file '{Path.GetFullPath(outputFile)}' for grammar '{g.fileName}'");

            Directory.CreateDirectory(outputDir);

            return(new StreamWriter(File.Open(outputFile, FileMode.Create), Encoding.GetEncoding(grammarEncoding)));
        }
        public static int Execute(IReadOnlyList <Instruction.IInstruction> instructions)
        {
            // # Context
            AdminShellPackageEnv package = null;

            // # Execution loop

            foreach (var instruction in instructions)
            {
                // The instruction dispatch is intentionally implemented as a switch statement and case blocks
                // instead of encapsulating the individual blocks in separate methods or classes. The shared context
                // is clearly signaled, while we do not gain much in clarity with separate functions and classes.
                //
                // Moreover, the pre-emptive stops in the execution logic were much more difficult to get right with the
                // methods than with this fairly simple construct.
                switch (instruction)
                {
                case Instruction.Generate generate:
                {
                    try
                    {
                        package = AasxToolkit.Generate.GeneratePackage(generate.JsonInitFile);
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(
                            "Failed to generate the package: {0} at {1}", ex.Message, ex.StackTrace);
                        return(-1);
                    }

                    Console.Out.WriteLine("Package generated.");
                    break;
                }

                case Instruction.Load load:
                {
                    Console.Out.WriteLine("Loading package {0} ..", load.Path);

                    try
                    {
                        if (load.Path.EndsWith(".aml"))
                        {
                            package = new AdminShellPackageEnv();
                            AmlImport.ImportInto(package, load.Path);
                        }
                        else
                        {
                            package = new AdminShellPackageEnv(load.Path);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(
                            "While loading package {0}: {1} at {2}", load.Path, ex.Message, ex.StackTrace);
                        return(-1);
                    }

                    Console.Out.WriteLine($"Loaded package: {load.Path}");
                    break;
                }

                case Instruction.Save save:
                {
                    if (package == null)
                    {
                        Console.Error.WriteLine(
                            "You must either generate a package (`gen`) or " +
                            "load a package (`load`) before you can save it.");
                        return(-1);
                    }

                    Console.Out.WriteLine("Writing package {0} ..", save.Path);

                    try
                    {
                        if (Path.GetExtension(save.Path).ToLower() == ".aml")
                        {
                            AmlExport.ExportTo(
                                package, save.Path, tryUseCompactProperties: false);
                        }
                        else
                        {
                            package.SaveAs(save.Path, writeFreshly: true);
                            package.Close();
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(
                            "While saving package {0}: {1} at {2}", save.Path, ex.Message, ex.StackTrace);
                        return(-1);
                    }

                    break;
                }

                case Instruction.Validate validate:
                {
                    try
                    {
                        var recs = new AasValidationRecordList();

                        string extension = Path.GetExtension(validate.Path).ToLower();
                        if (extension == ".xml")
                        {
                            Console.Out.WriteLine($"Validating file {validate.Path} against XSD ..");

                            using (var stream = File.Open(validate.Path, FileMode.Open, FileAccess.Read))
                            {
                                AasSchemaValidation.ValidateXML(recs, stream);
                            }
                        }
                        else if (extension == ".json")
                        {
                            Console.Out.WriteLine($"Validating file {validate.Path} against JSON ..");
                            using (var stream = File.Open(validate.Path, FileMode.Open, FileAccess.Read))
                            {
                                AasSchemaValidation.ValidateJSONAlternative(recs, stream);
                            }
                        }
                        else
                        {
                            throw new System.InvalidOperationException(
                                      $"Validation of the file with the extension {extension} " +
                                      $"is not supported: {validate.Path}");
                        }

                        if (recs.Count > 0)
                        {
                            Console.Out.WriteLine($"Found {recs.Count} issue(s):");
                            foreach (var r in recs)
                            {
                                Console.Out.WriteLine(r.ToString());
                            }
                        }
                        else
                        {
                            Console.Out.WriteLine($"Found no issues.");
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(
                            $"While validating the package {validate.Path}: " +
                            $"{ex.Message} at {ex.StackTrace}");
                        return(-1);
                    }

                    break;
                }

                case Instruction.ExportTemplate exportTemplate:
                {
                    if (package == null)
                    {
                        Console.Error.WriteLine(
                            "You must either generate a package (`gen`) or " +
                            "load a package (`load`) before you can export it as a template.");
                        return(-1);
                    }

                    Console.Out.WriteLine("Exporting to file {0} ..", exportTemplate.Path);

                    try
                    {
                        AasFormUtils.ExportAsTemplate(package, exportTemplate.Path);
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(
                            "While exporting package {0}: {1} at {2}",
                            exportTemplate.Path, ex.Message, ex.StackTrace);
                        return(-1);
                    }

                    Console.Out.WriteLine("Package {0} written.", exportTemplate.Path);
                    break;
                }

                case Instruction.ExportCst ecst:
                {
                    if (package == null)
                    {
                        Console.Error.WriteLine(
                            "You must either generate a package (`gen`) or " +
                            "load a package (`load`) before you can export it as a template.");
                        return(-1);
                    }

                    Console.Out.WriteLine("Exporting to file {0} ..", ecst.Path);

                    try
                    {
                        var ei = new AasxFormatCst.AasxToCst(jsonKnownIds: "cst-default-id-map.json");

                        var dnp = new AasxPredefinedConcepts.DefinitionsZveiDigitalTypeplate.SetOfNameplate(
                            new AasxPredefinedConcepts.DefinitionsZveiDigitalTypeplate());

                        ei.DoNotAddMultipleBlockRecordsWithSameIds = true;         // requested by Siemens

                        ei.ExportSingleSubmodel(
                            package, ecst.Path,
                            dnp.SM_Nameplate.GetSemanticKey(),
                            dnp.GetAllReferables(),
                            firstNodeId: new AasxFormatCst.CstIdObjectBase()
                            {
                                Namespace = "IDTA",
                                ID        = "FESTOAAS",
                                Revision  = "001",
                                Name      = "Festo"
                            },
                            secondNodeId: new AasxFormatCst.CstIdObjectBase()
                            {
                                Namespace = "IDTA",
                                ID        = "FESTOSM",
                                Revision  = "001",
                                Name      = "Submodel Nameplate"
                            },
                            appClassId: new AasxFormatCst.CstIdObjectBase()
                            {
                                Namespace  = "IDTA",
                                ObjectType = "01",
                                ID         = "SMNP001",
                                Revision   = "001",
                                Name       = "Submodel Nameplate"
                            });
                        AasFormUtils.ExportAsTemplate(package, ecst.Path);
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(
                            "While exporting CST {0}: {1} at {2}",
                            ecst.Path, ex.Message, ex.StackTrace);
                        return(-1);
                    }

                    Console.Out.WriteLine("File {0} written.", ecst.Path);
                    break;
                }

                case Instruction.CheckAndFix checkAndFix:
                {
                    try
                    {
                        if (package == null)
                        {
                            Console.Error.WriteLine(
                                "You must either generate a package (`gen`) or " +
                                "load a package (`load`) before you can check it.");
                            return(-1);
                        }

                        // validate
                        var recs = package?.AasEnv?.ValidateAll();
                        if (recs == null)
                        {
                            throw new InvalidOperationException(
                                      "Validation returned null -- we do not know how to handle this situation.");
                        }

                        if (recs.Count > 0)
                        {
                            Console.Out.WriteLine($"Found {recs.Count} issue(s):");
                            foreach (var rec in recs)
                            {
                                Console.Out.WriteLine(rec.ToString());
                            }

                            if (checkAndFix.ShouldFix)
                            {
                                Console.Out.WriteLine($"Fixing all records..");
                                var i = package.AasEnv.AutoFix(recs);
                                Console.Out.WriteLine($".. gave result {i}.");
                            }
                        }
                        else
                        {
                            Console.Out.WriteLine($"Found no issues.");
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(
                            "While checking the package in RAM: {0} at {1}", ex.Message, ex.StackTrace);
                        return(-1);
                    }

                    break;
                }

                case Instruction.Test _:
                {
                    try
                    {
                        if (package == null)
                        {
                            Console.Error.WriteLine(
                                "You must either generate a package (`gen`) or " +
                                "load a package (`load`) before you can test it.");
                            return(-1);
                        }

                        var prop = AdminShellV20.Property.CreateNew("test", "cat01");
                        prop.semanticId = new AdminShellV20.SemanticId(
                            AdminShellV20.Reference.CreateNew(
                                "GlobalReference", false, "IRI",
                                "www.admin-shell.io/nonsense"));

                        var fil = AdminShellV20.File.CreateNew("test", "cat01");
                        fil.semanticId = new AdminShellV20.SemanticId(
                            AdminShellV20.Reference.CreateNew(
                                "GlobalReference", false, "IRI",
                                "www.admin-shell.io/nonsense"));
                        fil.parent = fil;

                        var so = new AdminShellUtil.SearchOptions();
                        so.allowedAssemblies = new[] { typeof(AdminShell).Assembly };
                        var sr = new AdminShellUtil.SearchResults();

                        AdminShellUtil.EnumerateSearchable(
                            sr, package.AasEnv, "", 0, so);

                        // test debug
                        foreach (var fr in sr.foundResults)
                        {
                            Console.Out.WriteLine(
                                "{0}|{1} = {2}", fr.qualifiedNameHead, fr.metaModelName, fr.foundText);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(
                            "While testing the package in RAM: {0} at {1}", ex.Message, ex.StackTrace);
                        return(-1);
                    }

                    break;
                }

                default:
                    throw ExhaustiveMatching.ExhaustiveMatch.Failed(instruction);
                }
            }

            return(0);
        }