diff --git a/.vscode/launch.json b/.vscode/launch.json index a2a5e0235e..8ff5b089dd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,14 @@ "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. "program": "${workspaceFolder}/src/kiota/bin/Debug/net5.0/kiota.dll", - "args": [], + "args": ["--openapi", + "C:/sources/github/msgraph-sdk-powershell/openApiDocs/v1.0/mail.yml", + "--language", + "java", + "-o", + "C:/Users/vibiret/Desktop/graphjavav4/utilities/src/main/java/graphjavav4/utilities", + "-n", + "graphjavav4.utilities" ], "cwd": "${workspaceFolder}/src/kiota", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console": "internalConsole", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 22694d6de3..0625171b28 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -5,6 +5,7 @@ "label": "build", "command": "dotnet", "type": "process", + "group": "build", "args": [ "build", "${workspaceFolder}/src/kiota/kiota.csproj", @@ -13,10 +14,24 @@ ], "problemMatcher": "$msCompile" }, + { + "label": "test", + "command": "dotnet", + "type": "process", + "group": "test", + "args": [ + "test", + "${workspaceFolder}/tests/kiota.core.tests/kiota.core.tests.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, { "label": "publish", "command": "dotnet", "type": "process", + "group": "none", "args": [ "publish", "${workspaceFolder}/src/kiota/kiota.csproj", @@ -29,6 +44,7 @@ "label": "watch", "command": "dotnet", "type": "process", + "group": "build", "args": [ "watch", "run", diff --git a/src/kiota.core/GenerationConfiguration.cs b/src/kiota.core/GenerationConfiguration.cs index 0c8eb5a272..37d8b40fbb 100644 --- a/src/kiota.core/GenerationConfiguration.cs +++ b/src/kiota.core/GenerationConfiguration.cs @@ -3,6 +3,7 @@ public class GenerationConfiguration { public string OpenAPIFilePath { get; set; } = "openapi.yaml"; public string OutputPath { get; set; } = "./output"; public string ClientClassName { get; set; } = "GraphClient"; + public string ClientNamespaceName { get; set; } = "GraphClient"; public GenerationLanguage Language { get; set; } = GenerationLanguage.CSharp; } } diff --git a/src/kiota.core/KiotaBuilder.cs b/src/kiota.core/KiotaBuilder.cs index beeed246cd..d8bcab9d69 100644 --- a/src/kiota.core/KiotaBuilder.cs +++ b/src/kiota.core/KiotaBuilder.cs @@ -113,7 +113,7 @@ public CodeNamespace CreateSourceModel(OpenApiUrlSpaceNode root) var stopwatch = new Stopwatch(); stopwatch.Start(); - var codeNamespace = new CodeNamespace() { Name = this.config.ClientClassName }; + var codeNamespace = new CodeNamespace() { Name = this.config.ClientNamespaceName }; CreateClass(codeNamespace, root); stopwatch.Stop(); @@ -161,6 +161,9 @@ public async Task CreateLanguageSourceFilesAsync(GenerationLanguage language, Co case GenerationLanguage.CSharp: languageWriter = new CSharpWriter(); break; + case GenerationLanguage.Java: + languageWriter = new JavaWriter(); + break; default: throw new ArgumentException($"{language} language currently not supported."); } diff --git a/src/kiota.core/Writers/CSharpWriter.cs b/src/kiota.core/Writers/CSharpWriter.cs index fb3610e2c1..50a9f3e2ac 100644 --- a/src/kiota.core/Writers/CSharpWriter.cs +++ b/src/kiota.core/Writers/CSharpWriter.cs @@ -56,7 +56,7 @@ public override void WriteType(CodeType code) } - private string GetTypeString(CodeType code) + public override string GetTypeString(CodeType code) { var typeName = TranslateType(code.Name, code.Schema); if (code.ActionOf) @@ -69,7 +69,7 @@ private string GetTypeString(CodeType code) } } - private static string TranslateType(string typeName, OpenApiSchema schema) + public override string TranslateType(string typeName, OpenApiSchema schema) { switch (typeName) { @@ -83,7 +83,7 @@ private static string TranslateType(string typeName, OpenApiSchema schema) return typeName; } - private string GetParameterSignature(CodeParameter parameter) + public override string GetParameterSignature(CodeParameter parameter) { return $"{GetTypeString(parameter.Type)} {parameter.Name}"; } diff --git a/src/kiota.core/Writers/JavaWriter.cs b/src/kiota.core/Writers/JavaWriter.cs new file mode 100644 index 0000000000..b829589617 --- /dev/null +++ b/src/kiota.core/Writers/JavaWriter.cs @@ -0,0 +1,102 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.OpenApi.Models; + +namespace kiota.core +{ + public class JavaWriter : LanguageWriter + { + public override string GetFileSuffix() => ".java"; + + public override string GetParameterSignature(CodeParameter parameter) + { + return $"@javax.annotation.Nonnull final {GetTypeString(parameter.Type)} {parameter.Name}"; + } + + public override string GetTypeString(CodeType code) + { + var typeName = TranslateType(code.Name, code.Schema); + if (code.ActionOf) + { + return $"java.util.function.Consumer<{typeName}>"; + } + else + { + return typeName; + } + } + + public override string TranslateType(string typeName, OpenApiSchema schema) + { + switch (typeName) + {//TODO we're probably missing a bunch of type mappings + case "integer": return "Integer"; + case "boolean": return "Boolean"; + case "string": return "String"; + case "object": return "Object"; + case "array": return $"{TranslateType(schema.Items.Type, schema.Items)}[]"; + } + + return typeName; + } + + public override void WriteCodeClassDeclaration(CodeClass.Declaration code) + { + //TODO: missing javadoc + WriteLine($"public class {code.Name} {{"); + IncreaseIndent(); + } + + public override void WriteCodeClassEnd(CodeClass.End code) + { + DecreaseIndent(); + WriteLine("}"); + } + + public override void WriteIndexer(CodeIndexer code) + { + WriteMethod(new CodeMethod { + Name = "get", + Parameters = new List { + new CodeParameter { + Name = "position", + Type = code.IndexType, + Optional = false, + } + }, + ReturnType = code.IndexType + }); + } + + public override void WriteMethod(CodeMethod code) + { + //TODO javadoc + WriteLine("@javax.annotation.Nonnull"); + WriteLine($"public java.util.concurrent.Future<{GetTypeString(code.ReturnType)}> {code.Name}({string.Join(',', code.Parameters.Select(p=> GetParameterSignature(p)).ToList())}) {{ return null; }}"); + } + + public override void WriteNamespaceDeclaration(CodeNamespace.Declaration code) + { + WriteLine($"package {code.Name};"); + WriteLine(); + foreach (var codeUsing in code.Usings) + { + WriteLine($"import {codeUsing.Name}.*;"); + } + } + + public override void WriteNamespaceEnd(CodeNamespace.End code) => WriteLine(); + + public override void WriteProperty(CodeProperty code) + { + //TODO: missing javadoc + WriteLine("@javax.annotation.Nullable"); + WriteLine($"public {GetTypeString(code.Type)} {code.Name};"); + } + + public override void WriteType(CodeType code) + { + Write(GetTypeString(code), includeIndent: false); + } + } +} diff --git a/src/kiota.core/Writers/LanguageWriter.cs b/src/kiota.core/Writers/LanguageWriter.cs index c5268c1be0..d2207eec40 100644 --- a/src/kiota.core/Writers/LanguageWriter.cs +++ b/src/kiota.core/Writers/LanguageWriter.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using Microsoft.OpenApi.Models; namespace kiota.core { @@ -39,7 +40,10 @@ public string GetIndent() { return indentString.Substring(0, currentIndent); } - + /// + /// Adds an empty line + /// + protected void WriteLine() => WriteLine(string.Empty, false); protected void WriteLine(string line, bool includeIndent = true) { writer.WriteLine(includeIndent ? GetIndent() + line : line); @@ -73,36 +77,16 @@ public void Write(CodeElement code) } - - public virtual void WriteProperty(CodeProperty code) - { - } - - public virtual void WriteIndexer(CodeIndexer code) - { - } - public virtual void WriteMethod(CodeMethod code) - { - } - - public virtual void WriteType(CodeType code) - { - } - - public virtual void WriteNamespaceEnd(CodeNamespace.End code) - { - } - - public virtual void WriteNamespaceDeclaration(CodeNamespace.Declaration code) - { - } - - public virtual void WriteCodeClassDeclaration(CodeClass.Declaration code) - { - } - - public virtual void WriteCodeClassEnd(CodeClass.End code) - { - } + public abstract string GetParameterSignature(CodeParameter parameter); + public abstract string GetTypeString(CodeType code); + public abstract string TranslateType(string typeName, OpenApiSchema schema); + public abstract void WriteProperty(CodeProperty code); + public abstract void WriteIndexer(CodeIndexer code); + public abstract void WriteMethod(CodeMethod code); + public abstract void WriteType(CodeType code); + public abstract void WriteNamespaceEnd(CodeNamespace.End code); + public abstract void WriteNamespaceDeclaration(CodeNamespace.Declaration code); + public abstract void WriteCodeClassDeclaration(CodeClass.Declaration code); + public abstract void WriteCodeClassEnd(CodeClass.End code); } } diff --git a/src/kiota/Program.cs b/src/kiota/Program.cs index ae9fa4147f..1d3c500686 100644 --- a/src/kiota/Program.cs +++ b/src/kiota/Program.cs @@ -22,12 +22,14 @@ static async Task Main(string[] args) private static RootCommand GetRootCommand(GenerationConfiguration configuration) { - var outputOption = new Option("--output", "The ouput path of the folder the code will be generated in.") { Argument = new Argument() }; + var outputOption = new Option("--output", "The ouput path of the folder the code will be generated in.") { Argument = new Argument(() => "./output") }; outputOption.AddAlias("-o"); - var languageOption = new Option("--language", "The language to generate the code in.") { Argument = new Argument() }; + var languageOption = new Option("--language", "The language to generate the code in.") { Argument = new Argument(() => GenerationLanguage.CSharp) }; languageOption.AddAlias("-l"); - var classOption = new Option("--class-name", "The class name to use the for main entry point") { Argument = new Argument() }; + var classOption = new Option("--class-name", "The class name to use the for main entry point") { Argument = new Argument(() => "GraphClient") }; classOption.AddAlias("-c"); + var namespaceOption = new Option("--namespace-name", "The namespace name to use the for main entry point") { Argument = new Argument(() => "GraphClient") }; + namespaceOption.AddAlias("-n"); var command = new RootCommand { outputOption, @@ -35,8 +37,9 @@ private static RootCommand GetRootCommand(GenerationConfiguration configuration) new Option("--openapi", "The path to the OpenAPI description file used to generate the code.") {Argument = new Argument(() => "openapi.yml")}, classOption, new Option("--loglevel") { Argument = new Argument(() => LogLevel.Warning)}, + namespaceOption, }; - command.Handler = CommandHandler.Create(async (output, language, openapi, classname, loglevel) => + command.Handler = CommandHandler.Create(async (output, language, openapi, classname, loglevel, namespacename) => { if (!string.IsNullOrEmpty(output)) configuration.OutputPath = output; @@ -44,6 +47,8 @@ private static RootCommand GetRootCommand(GenerationConfiguration configuration) configuration.OpenAPIFilePath = openapi; if (!string.IsNullOrEmpty(classname)) configuration.ClientClassName = classname; + if (!string.IsNullOrEmpty(namespacename)) + configuration.ClientNamespaceName = namespacename; if (language.HasValue) configuration.Language = language.Value;