Skip to content

Commit

Permalink
[Java.Interop.Maven] Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpobst committed Jan 12, 2024
1 parent def5bc0 commit c1b64bb
Show file tree
Hide file tree
Showing 22 changed files with 7,656 additions and 0 deletions.
14 changes: 14 additions & 0 deletions Java.Interop.sln
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Tools.Expressi
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Tools.Expressions-Tests", "tests\Java.Interop.Tools.Expressions-Tests\Java.Interop.Tools.Expressions-Tests.csproj", "{211BAA88-66B1-41B2-88B2-530DBD8DF702}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Maven", "src\Java.Interop.Maven\Java.Interop.Maven.csproj", "{DA458F90-218B-4FE3-995F-AF4B27895FA2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Maven-Tests", "tests\Java.Interop.Maven-Tests\Java.Interop.Maven-Tests.csproj", "{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems*{58b564a1-570d-4da2-b02d-25bddb1a9f4f}*SharedItemsImports = 5
Expand Down Expand Up @@ -320,6 +324,14 @@ Global
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Debug|Any CPU.Build.0 = Debug|Any CPU
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Release|Any CPU.ActiveCfg = Release|Any CPU
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Release|Any CPU.Build.0 = Release|Any CPU
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Release|Any CPU.Build.0 = Release|Any CPU
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -374,6 +386,8 @@ Global
{CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{1A0262FE-3CDB-4AF2-AAD8-65C59524FE8A} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{211BAA88-66B1-41B2-88B2-530DBD8DF702} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{DA458F90-218B-4FE3-995F-AF4B27895FA2} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {29204E0C-382A-49A0-A814-AD7FBF9774A5}
Expand Down
8 changes: 8 additions & 0 deletions build-tools/automation/templates/core-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ steps:
arguments: bin/Test$(Build.Configuration)$(NetCoreTargetFrameworkPathSuffix)/Xamarin.SourceWriter-Tests.dll
continueOnError: true

- task: DotNetCoreCLI@2
displayName: 'Tests: Java.Interop.Maven'
inputs:
command: test
testRunTitle: Java.Interop.Maven (${{ parameters.platformName }})
arguments: bin/Test$(Build.Configuration)$(NetCoreTargetFrameworkPathSuffix)/Java.Interop.Maven-Tests.dll
continueOnError: true

- task: DotNetCoreCLI@2
displayName: 'Tests: Java.Interop'
condition: or(eq('${{ parameters.runNativeDotnetTests }}', 'true'), eq('${{ parameters.runNativeTests }}', 'true'))
Expand Down
23 changes: 23 additions & 0 deletions src/Java.Interop.Maven/DefaultPomResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using Java.Interop.Maven.Models;

namespace Java.Interop.Maven;

public class DefaultPomResolver : IPomResolver
{
readonly Dictionary<string, Project> poms = new ();

public void Register (Project project)
{
poms.Add (project.ToString (), project);
}

public virtual Project ResolveRawProject (Artifact artifact)
{
if (poms.TryGetValue (artifact.ToString (), out var project))
return project;

throw new InvalidOperationException ($"No POM registered for {artifact}");
}
}
76 changes: 76 additions & 0 deletions src/Java.Interop.Maven/Extensions/MavenNetExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Java.Interop.Maven.Models;

namespace Java.Interop.Maven.Extensions;

static class MavenNetExtensions
{
public static bool HasValue ([NotNullWhen (true)] this string? str) => !string.IsNullOrEmpty (str);

public static string OrEmpty (this string? str) => str ?? string.Empty;

public static string GetInheritedProperty (this ResolvedDependency dependency, ResolvedProject project, Func<ResolvedDependency, string?> property)
{
// Check our <dependencyManagement> section
if (CheckDependencyManagementSection (project, dependency, property, out var result))
return result;

// Check imported POMs
foreach (var imported in project.ImportedPomProjects) {
var value = GetInheritedProperty (dependency, imported, property);

if (value.HasValue ())
return value;
}

// Check parent POM
if (project.Parent is not null && !project.Parent.IsSuperPom)
return GetInheritedProperty (dependency, project.Parent, property);

return string.Empty;
}

static bool CheckImportedPoms (ResolvedDependency dependency, ResolvedProject project, Func<ResolvedDependency, string?> property, [NotNullWhen (true)] out string? result)
{
result = null;

foreach (var imported in project.ImportedPomProjects) {
var imported_dep = imported.Resolved.DependencyManagement?.Dependencies.FirstOrDefault (x => x.ArtifactId == dependency.ArtifactId && x.GroupId == dependency.GroupId);

if (imported_dep != null) {
result = property (new ResolvedDependency (imported, imported_dep, true));

if (result.HasValue ())
return true;
}

// Recurse, as imported POMs can also import POMs
if (CheckImportedPoms (dependency, imported, property, out result))
return true;
}

return false;
}

static bool CheckDependencyManagementSection (ResolvedProject project, ResolvedDependency dependency, Func<ResolvedDependency, string?> property, [NotNullWhen (true)] out string? result)
{
result = null;

// Check <dependencyManagement>
var dep_man = project.Resolved.DependencyManagement?.Dependencies.FirstOrDefault (x => x.ArtifactId == dependency.ArtifactId && x.GroupId == dependency.GroupId);

if (dep_man != null) {
result = property (new ResolvedDependency (project, dep_man, true)) ?? string.Empty;
return result.HasValue ();
}

return false;
}

public static Artifact ToArtifact (this Dependency dependency)
{
return new Artifact (dependency.GroupId.OrEmpty (), dependency.ArtifactId.OrEmpty ().OrEmpty (), dependency.Version.OrEmpty ());
}
}
42 changes: 42 additions & 0 deletions src/Java.Interop.Maven/Extensions/PropertyStack.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Xml.Linq;
using Java.Interop.Maven.Models;

namespace Java.Interop.Maven.Extensions;

class PropertyStack
{
// Why go to this trouble?
// A property can be specified in both a child POM and its parent POM.
// Even if the property is being consumed in the parent POM, the property in
// the child POM takes precedence.
readonly List<List<KeyValuePair<string, string>>> stack = new ();

public void Push (ModelProperties? properties)
{
// We add a new list to the stack, even if it's empty, so that the Pop works later
var list = new List<KeyValuePair<string, string>> ();

if (properties?.Any is Collection<XElement> props)
foreach (var prop in props)
list.Add (new KeyValuePair<string, string> (prop.Name.LocalName, prop.Value));

stack.Add (list);
}

public void Pop ()
{
stack.RemoveAt (stack.Count - 1);
}

public string Apply (string value)
{
foreach (var property_set in stack) {
foreach (var prop in property_set)
value = value.Replace ($"${{{prop.Key}}}", prop.Value);
}

return value;
}
}
8 changes: 8 additions & 0 deletions src/Java.Interop.Maven/IPomResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Java.Interop.Maven.Models;

namespace Java.Interop.Maven;

public interface IPomResolver
{
Project ResolveRawProject (Artifact artifact);
}
25 changes: 25 additions & 0 deletions src/Java.Interop.Maven/Java.Interop.Maven.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>11.0</LangVersion>
<Nullable>enable</Nullable>
<DefineConstants>INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
<Nullable>enable</Nullable>
</PropertyGroup>

<Import Project="..\..\TargetFrameworkDependentValues.props" />

<PropertyGroup>
<OutputPath>$(UtilityOutputFullPath)</OutputPath>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\utils\NullableAttributes.cs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
</ItemGroup>

</Project>
31 changes: 31 additions & 0 deletions src/Java.Interop.Maven/Models/Artifact.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;

namespace Java.Interop.Maven.Models;

public class Artifact
{
public string GroupId { get; }

public string Id { get; }

public string Version { get; }

public Artifact (string groupId, string artifactId, string version)
{
Id = artifactId;
GroupId = groupId;
Version = version;
}

public static Artifact Parse (string value)
{
var parts = value.Split (':');

if (parts.Length != 3)
throw new ArgumentException ($"Invalid artifact format: {value}");

return new Artifact (parts [0], parts [1], parts [2]);
}

public override string ToString () => $"{GroupId}:{Id}:{Version}";
}
62 changes: 62 additions & 0 deletions src/Java.Interop.Maven/Models/Project.Partial.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using Java.Interop.Maven.Extensions;

namespace Java.Interop.Maven.Models;

public partial class Project
{
public static Project? Parse (Stream stream)
{
Project? result = null;

var serializer = new XmlSerializer (typeof (Project));

using (var sr = new StreamReader (stream))
result = (Project?) serializer.Deserialize (new XmlTextReader (sr) {
Namespaces = false,
});

return result;
}

public static Project? ParseXml (string xml)
{
Project? result = null;

var serializer = new XmlSerializer (typeof (Project));

using (var sr = new StringReader (xml))
result = (Project?) serializer.Deserialize (new XmlTextReader (sr) {
Namespaces = false,
});

return result;
}

public bool TryGetParentPomArtifact ([NotNullWhen (true)] out Artifact? parent)
{
parent = null;

if (Parent is not null) {
parent = new Artifact (Parent.GroupId.OrEmpty (), Parent.ArtifactId.OrEmpty (), Parent.Version.OrEmpty ());
return true;
}

return false;
}

public override string ToString () => $"{GroupId}:{ArtifactId}:{Version}";

public string ToXml ()
{
var serializer = new XmlSerializer (typeof (Project));

using (var sw = new StringWriter ()) {
serializer.Serialize (sw, this);
return sw.ToString ();
}
}
}
Loading

0 comments on commit c1b64bb

Please sign in to comment.