예제 #1
0
        public void Generate(UblGeneratorOptions options)
        {
            Console.WriteLine("Validating options...");

            _options = options;
            options.Validate();

            var baseInputDirectory = options.XsdBasePath;
            var maindocfiles       = new List <FileInfo>();

            if (!string.IsNullOrEmpty(baseInputDirectory))
            {
                maindocfiles = new DirectoryInfo(baseInputDirectory).GetFiles("*.xsd").ToList();
            }

            var maindocSchemaSet = new XmlSchemaSet()
            {
                // XmlResolver = xsdResolver
                // XmlResolver = null
            };

            Console.WriteLine("Read common UBL files from embedded resources...");

            var nameTable      = new NameTable();
            var readerSettings = new XmlReaderSettings
            {
                ValidationType = ValidationType.Schema,
                DtdProcessing  = DtdProcessing.Parse,
                NameTable      = nameTable
            };

            AddCommonFiles(maindocSchemaSet, readerSettings);

            Console.WriteLine($"Add schema files from {baseInputDirectory}...");

            var schemasToGenerate = new List <XmlSchema>();

            foreach (var maindocfile in maindocfiles)
            {
                using (var reader = XmlReader.Create(maindocfile.FullName, readerSettings))
                {
                    var schema = XmlSchema.Read(reader, null);

                    // ReplaceKnownSchemaIncludes(schema, knownSchema);
                    maindocSchemaSet.Add(schema);
                    schemasToGenerate.Add(schema);
                }
            }

            Console.WriteLine("Fixing schema...");

            maindocSchemaSet.Compile();

            foreach (var schemaFixer in _schemaFixers)
            {
                schemaFixer(maindocSchemaSet);
                maindocSchemaSet.Compile();
            }

            Console.WriteLine("Creating compile unit...");

            var namespaceProvider = new CodeNamespaceProvider(maindocSchemaSet, options);
            var compileUnit       = CreateCodeNamespace(maindocSchemaSet, namespaceProvider);

            foreach (var ns in compileUnit.Namespaces.OfType <CodeNamespace>())
            {
                _globalCodeFixer.Fix(ns);
            }

            var codeProvider   = new CSharpCodeProvider();
            var codegenOptions = new CodeGeneratorOptions()
            {
                BracingStyle             = "C",
                IndentString             = "    ",
                BlankLinesBetweenMembers = true,
                VerbatimOrder            = true
            };

            Console.WriteLine("Generating source files...");

            if (options.GenerateCommonFiles)
            {
                foreach (var schema in maindocSchemaSet.Schemas().Cast <XmlSchema>())
                {
                    GenerateCodeForSchema(options, compileUnit, namespaceProvider, codeProvider, codegenOptions, schema);
                }
            }
            else
            {
                foreach (var schema in schemasToGenerate)
                {
                    GenerateCodeForSchema(options, compileUnit, namespaceProvider, codeProvider, codegenOptions, schema);
                }
            }
        }
예제 #2
0
        private void GenerateCodeForSchema(UblGeneratorOptions options, CodeCompileUnit compileUnit, CodeNamespaceProvider namespaceProvider, CSharpCodeProvider codeProvider, CodeGeneratorOptions codegenOptions, XmlSchema schema)
        {
            var tmpCodeNamespace  = compileUnit.Namespaces.OfType <CodeNamespace>().Single(x => x.UserData[CodeTypeMemberExtensions.XmlSchemaKey] == schema);
            var codeDeclsBySchema = (from t in tmpCodeNamespace.Types.Cast <CodeTypeDeclaration>()
                                     group t by t.GetSchema()
                                     into g
                                     select g)
                                    .ToDictionary(k => k.Key, v => v.ToArray());

            var codeNamespace = namespaceProvider.CreateCodeNamespace(schema);

            if (codeDeclsBySchema.ContainsKey(schema))
            {
                codeNamespace.Types.AddRange(codeDeclsBySchema[schema]);
            }

            if (codeNamespace.Types.Count == 0)
            {
                return;
            }

            _namespacedCodeFixer.Fix(codeNamespace);

            var sb = new StringBuilder();

            using (var sw = new StringWriter(sb))
            {
                codeProvider.GenerateCodeFromNamespace(codeNamespace, sw, codegenOptions);
            }

            sb = sb.Replace("Namespace=\"", "Namespace = \"");

            var fileContent = sb.ToString();
            var lines       = fileContent.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList();

            foreach (var fixer in _conditionalFeatureFixers)
            {
                int lineNum = 0;
                while (true)
                {
                    lineNum = fixer(lines, lineNum);
                    if (lineNum < 0)
                    {
                        break;
                    }
                }
            }

            sb = new StringBuilder(string.Join(Environment.NewLine, lines));

            var    xsdFilename = new Uri(schema.SourceUri).LocalPath;
            var    fi          = new FileInfo(xsdFilename);
            var    foldername  = namespaceProvider.GetNamespaceFolderName(schema);
            string targetPath  = Path.Combine(options.OutputPath, foldername);

            if (!Directory.Exists(targetPath))
            {
                Directory.CreateDirectory(targetPath);
            }

            var outputFile = Path.Combine(targetPath, Path.ChangeExtension(fi.Name, ".generated.cs"));

            using (var ofile = File.CreateText(outputFile))
            {
                ofile.Write(sb);
                Console.WriteLine($"Written: {outputFile}");
            }
        }
예제 #3
0
        private CodeCompileUnit CreateCodeNamespace(XmlSchemaSet schemaSet, CodeNamespaceProvider namespaceProvider)
        {
            var compileUnit = new CodeCompileUnit();
            var schemas     = new XmlSchemas();

            foreach (var s in schemaSet.Schemas())
            {
                schemas.Add((XmlSchema)s);
            }

            schemas.Compile(_options.ValidationHandler, true);

            foreach (XmlSchema schema in schemas)
            {
                var codeNamespace = namespaceProvider.CreateCodeNamespace(schema);
                compileUnit.Namespaces.Add(codeNamespace);
            }

            var codeOptions = CodeGenerationOptions.GenerateOrder | CodeGenerationOptions.GenerateNewAsync;

            // foreach (var ns in rootNamespaces.Concat(extensionNamespaces))
            foreach (XmlSchema schema in schemas)
            {
                var schemaImporter = new XmlSchemaImporter(schemas);
                schemaImporter.Extensions.Clear();

                // var schema = schemas[ns];
                var codeNamespace = compileUnit.Namespaces.OfType <CodeNamespace>().Single(x => x.UserData[CodeTypeMemberExtensions.XmlSchemaKey] == schema);

                Console.WriteLine($"Import root namespace: {schema.TargetNamespace}");

                var codeExporter = new XmlCodeExporter(codeNamespace, compileUnit, codeOptions);

                foreach (XmlSchemaElement element in schema.Elements.Values.OfType <XmlSchemaElement>())
                {
                    Console.WriteLine($"Import type mapping for {element.QualifiedName.Namespace} : {element.QualifiedName.Name}");
                    var xmlTypeMapping = schemaImporter.ImportTypeMapping(element.QualifiedName);
                    codeExporter.ExportTypeMapping(xmlTypeMapping);
                }

                var baseTypes = schema.Elements.Values.OfType <XmlSchemaElement>().Select(x => x.SchemaTypeName.Name).ToList();

                foreach (XmlSchemaComplexType element in schema.SchemaTypes.Values.OfType <XmlSchemaComplexType>().Where(x => !baseTypes.Contains(x.Name)))
                {
                    Console.WriteLine($"Import schema type for {element.QualifiedName.Namespace} : {element.QualifiedName.Name}");

                    var xmlTypeMapping = schemaImporter.ImportSchemaType(element.QualifiedName);
                    codeExporter.ExportTypeMapping(xmlTypeMapping);
                }
            }

            var codeDeclarations = compileUnit.Namespaces.OfType <CodeNamespace>().SelectMany(x => x.Types.Cast <CodeTypeDeclaration>()).ToList();

            foreach (var codeDecl in codeDeclarations)
            {
                codeDecl.Comments.Clear();
                foreach (var item in codeDecl.Members.OfType <CodeTypeMember>())
                {
                    item.Comments.Clear();
                }

                var qname = codeDecl.GetQualifiedName();
                codeDecl.UserData[CodeTypeMemberExtensions.QualifiedNameKey] = qname;
                // Note, this can fail when there are multiple schemas for one namespace, like urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2
                var schema = schemas.GetSchemas(qname.Namespace).OfType <XmlSchema>().FirstOrDefault();
                // var schema = schemas[qname.Namespace];
                codeDecl.UserData[CodeTypeMemberExtensions.XmlSchemaKey] = schema;
                var xmlSchemaType = (XmlSchemaType)schema.SchemaTypes[qname];
                codeDecl.UserData[CodeTypeMemberExtensions.XmlSchemaTypeKey] = xmlSchemaType;

                foreach (CodeTypeMember member in codeDecl.Members)
                {
                    member.UserData[CodeTypeMemberExtensions.XmlSchemaKey]     = schema;
                    member.UserData[CodeTypeMemberExtensions.XmlSchemaTypeKey] = xmlSchemaType;
                }
            }

            return(compileUnit);
        }
예제 #4
0
        public void Generate(UblGeneratorOptions options)
        {
            _options = options;
            options.Validate();

            var baseInputDirectory = options.XsdBasePath;
            var commonDirectory    = Path.Combine(baseInputDirectory, "common");
            var xmldsigFilename    = new DirectoryInfo(commonDirectory).GetFiles("UBL-xmldsig-core-schema-*.xsd").Single().FullName;
            var maindocDirectory   = Path.Combine(baseInputDirectory, "maindoc");
            var maindocfiles       = new DirectoryInfo(maindocDirectory).GetFiles("*.xsd").ToList();
            // var extrafiles = new DirectoryInfo(commonDirectory).GetFiles("UBL-CommonSignatureComponents*.xsd").ToList();
            // var maindocfiles = new DirectoryInfo(maindocDirectory).GetFiles("UBL-Order-2.1.xsd").ToList();
            // maindocfiles.Add(new DirectoryInfo(maindocDirectory).GetFiles("UBL-BaseDocument-*.xsd").Single());

            var maindocSchemaSet = new XmlSchemaSet();

            var nameTable      = new NameTable();
            var readerSettings = new XmlReaderSettings
            {
                ValidationType = ValidationType.Schema,
                DtdProcessing  = DtdProcessing.Parse,
                NameTable      = nameTable,
            };

            using (var reader = XmlReader.Create(xmldsigFilename, readerSettings))
            {
                var schema = XmlSchema.Read(reader, null);
                maindocSchemaSet.Add(schema);
            }

            foreach (var maindocfile in maindocfiles)
            {
                using (var reader = XmlReader.Create(maindocfile.FullName, readerSettings))
                {
                    var schema = XmlSchema.Read(reader, null);
                    maindocSchemaSet.Add(schema);
                }
            }

            //foreach (var extrafile in extrafiles)
            //{
            //    using (var reader = XmlReader.Create(extrafile.FullName, readerSettings))
            //    {
            //        var schema = XmlSchema.Read(reader, null);
            //        maindocSchemaSet.Add(schema);
            //    }
            //}

            maindocSchemaSet.Compile();

            foreach (var schemaFixer in _schemaFixers)
            {
                schemaFixer(maindocSchemaSet);
                maindocSchemaSet.Compile();
            }

            var rootNamespaces = maindocSchemaSet.Schemas().OfType <XmlSchema>()
                                 .Where(x => x.SourceUri.Contains("maindoc"))
                                 .Select(x => x.TargetNamespace)
                                 .Concat(new[]
            {
                Namespaces.Xmldsig,
                Namespaces.Sac,
                Namespaces.Csc,
                Namespaces.Xades141,
            });

            var tempCodeNamespace = CreateCodeNamespace(maindocSchemaSet, rootNamespaces.ToArray());

            _globalCodeFixer.Fix(tempCodeNamespace);

            var codeDeclsBySchema = (from t in tempCodeNamespace.Types.Cast <CodeTypeDeclaration>()
                                     group t by t.GetSchema() into g
                                     select g)
                                    .ToDictionary(k => k.Key, v => v.ToArray());

            var codeProvider   = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider();
            var codegenOptions = new CodeGeneratorOptions()
            {
                BracingStyle             = "C",
                IndentString             = "    ",
                BlankLinesBetweenMembers = true,
                VerbatimOrder            = true
            };

            var namespaceProvider = new CodeNamespaceProvider(maindocSchemaSet, options);

            foreach (var schema in maindocSchemaSet.Schemas().Cast <XmlSchema>())
            {
                var codeNamespace = namespaceProvider.CreateCodeNamespace(schema.TargetNamespace);
                if (codeDeclsBySchema.ContainsKey(schema))
                {
                    codeNamespace.Types.AddRange(codeDeclsBySchema[schema]);
                }

                if (codeNamespace.Types.Count == 0)
                {
                    continue;
                }

                _namespacedCodeFixer.Fix(codeNamespace);

                var sb = new StringBuilder();
                using (var sw = new StringWriter(sb))
                {
                    codeProvider.GenerateCodeFromNamespace(codeNamespace, sw, codegenOptions);
                }

                sb = sb.Replace("Namespace=\"", "Namespace = \"");

                var fileContent = sb.ToString();
                var lines       = fileContent.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList();

                foreach (var fixer in _conditionalFeatureFixers)
                {
                    int lineNum = 0;
                    while (true)
                    {
                        lineNum = fixer(lines, lineNum);
                        if (lineNum < 0)
                        {
                            break;
                        }
                    }
                }

                sb = new StringBuilder(string.Join(Environment.NewLine, lines));

                var    xsdFilename = new Uri(schema.SourceUri).LocalPath;
                var    fi          = new FileInfo(xsdFilename);
                var    foldername  = namespaceProvider.GetNamespaceFolderName(schema);
                string targetPath  = Path.Combine(options.OutputPath, foldername);
                if (!Directory.Exists(targetPath))
                {
                    Directory.CreateDirectory(targetPath);
                }
                var outputFile = Path.Combine(targetPath, Path.ChangeExtension(fi.Name, ".generated.cs"));

                using (var ofile = File.CreateText(outputFile))
                {
                    ofile.Write(sb);
                }
            }
        }