Skip to content

Commit 1bb76b2

Browse files
committed
[Java.Interop.Tools.Maven] Initial commit.
1 parent def5bc0 commit 1bb76b2

22 files changed

+7718
-0
lines changed

Java.Interop.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Tools.Expressi
113113
EndProject
114114
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}"
115115
EndProject
116+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Maven", "src\Java.Interop.Tools.Maven\Java.Interop.Tools.Maven.csproj", "{DA458F90-218B-4FE3-995F-AF4B27895FA2}"
117+
EndProject
118+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Maven-Tests", "tests\Java.Interop.Tools.Maven-Tests\Java.Interop.Tools.Maven-Tests.csproj", "{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}"
119+
EndProject
116120
Global
117121
GlobalSection(SharedMSBuildProjectFiles) = preSolution
118122
src\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems*{58b564a1-570d-4da2-b02d-25bddb1a9f4f}*SharedItemsImports = 5
@@ -320,6 +324,14 @@ Global
320324
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Debug|Any CPU.Build.0 = Debug|Any CPU
321325
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Release|Any CPU.ActiveCfg = Release|Any CPU
322326
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Release|Any CPU.Build.0 = Release|Any CPU
327+
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
328+
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
329+
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
330+
{DA458F90-218B-4FE3-995F-AF4B27895FA2}.Release|Any CPU.Build.0 = Release|Any CPU
331+
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
332+
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Debug|Any CPU.Build.0 = Debug|Any CPU
333+
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Release|Any CPU.ActiveCfg = Release|Any CPU
334+
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D}.Release|Any CPU.Build.0 = Release|Any CPU
323335
EndGlobalSection
324336
GlobalSection(SolutionProperties) = preSolution
325337
HideSolutionNode = FALSE
@@ -374,6 +386,8 @@ Global
374386
{CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
375387
{1A0262FE-3CDB-4AF2-AAD8-65C59524FE8A} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
376388
{211BAA88-66B1-41B2-88B2-530DBD8DF702} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
389+
{DA458F90-218B-4FE3-995F-AF4B27895FA2} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
390+
{6BC04C7F-949E-4F93-BF1F-E3B1DF0B888D} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
377391
EndGlobalSection
378392
GlobalSection(ExtensibilityGlobals) = postSolution
379393
SolutionGuid = {29204E0C-382A-49A0-A814-AD7FBF9774A5}

build-tools/automation/templates/core-tests.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ steps:
7676
arguments: bin/Test$(Build.Configuration)$(NetCoreTargetFrameworkPathSuffix)/Xamarin.SourceWriter-Tests.dll
7777
continueOnError: true
7878

79+
- task: DotNetCoreCLI@2
80+
displayName: 'Tests: Java.Interop.Maven'
81+
inputs:
82+
command: test
83+
testRunTitle: Java.Interop.Maven (${{ parameters.platformName }})
84+
arguments: bin/Test$(Build.Configuration)$(NetCoreTargetFrameworkPathSuffix)/Java.Interop.Maven-Tests.dll
85+
continueOnError: true
86+
7987
- task: DotNetCoreCLI@2
8088
displayName: 'Tests: Java.Interop'
8189
condition: or(eq('${{ parameters.runNativeDotnetTests }}', 'true'), eq('${{ parameters.runNativeTests }}', 'true'))
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Java.Interop.Tools.Maven.Models;
4+
5+
namespace Java.Interop.Tools.Maven;
6+
7+
public class DefaultPomResolver : IPomResolver
8+
{
9+
readonly Dictionary<string, Project> poms = new ();
10+
11+
public void Register (Project project)
12+
{
13+
poms.Add (project.ToString (), project);
14+
}
15+
16+
public virtual Project ResolveRawProject (Artifact artifact)
17+
{
18+
if (poms.TryGetValue (artifact.ToString (), out var project))
19+
return project;
20+
21+
throw new InvalidOperationException ($"No POM registered for {artifact}");
22+
}
23+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
using System.Linq;
4+
using Java.Interop.Tools.Maven.Models;
5+
6+
namespace Java.Interop.Tools.Maven.Extensions;
7+
8+
static class MavenNetExtensions
9+
{
10+
public static bool HasValue ([NotNullWhen (true)] this string? str) => !string.IsNullOrEmpty (str);
11+
12+
public static string OrEmpty (this string? str) => str ?? string.Empty;
13+
14+
public static string GetInheritedProperty (this ResolvedDependency dependency, ResolvedProject project, Func<ResolvedDependency, string?> property)
15+
{
16+
// Check our <dependencyManagement> section
17+
if (CheckDependencyManagementSection (project, dependency, property, out var result))
18+
return result;
19+
20+
// Check imported POMs
21+
foreach (var imported in project.ImportedPomProjects) {
22+
var value = GetInheritedProperty (dependency, imported, property);
23+
24+
if (value.HasValue ())
25+
return value;
26+
}
27+
28+
// Check parent POM
29+
if (project.Parent is not null && !project.Parent.IsSuperPom)
30+
return GetInheritedProperty (dependency, project.Parent, property);
31+
32+
return string.Empty;
33+
}
34+
35+
static bool CheckImportedPoms (ResolvedDependency dependency, ResolvedProject project, Func<ResolvedDependency, string?> property, [NotNullWhen (true)] out string? result)
36+
{
37+
result = null;
38+
39+
foreach (var imported in project.ImportedPomProjects) {
40+
var imported_dep = imported.Resolved.DependencyManagement?.Dependencies.FirstOrDefault (x => x.ArtifactId == dependency.ArtifactId && x.GroupId == dependency.GroupId);
41+
42+
if (imported_dep != null) {
43+
result = property (new ResolvedDependency (imported, imported_dep, true));
44+
45+
if (result.HasValue ())
46+
return true;
47+
}
48+
49+
// Recurse, as imported POMs can also import POMs
50+
if (CheckImportedPoms (dependency, imported, property, out result))
51+
return true;
52+
}
53+
54+
return false;
55+
}
56+
57+
static bool CheckDependencyManagementSection (ResolvedProject project, ResolvedDependency dependency, Func<ResolvedDependency, string?> property, [NotNullWhen (true)] out string? result)
58+
{
59+
result = null;
60+
61+
// Check <dependencyManagement>
62+
var dep_man = project.Resolved.DependencyManagement?.Dependencies.FirstOrDefault (x => x.ArtifactId == dependency.ArtifactId && x.GroupId == dependency.GroupId);
63+
64+
if (dep_man != null) {
65+
result = property (new ResolvedDependency (project, dep_man, true)) ?? string.Empty;
66+
return result.HasValue ();
67+
}
68+
69+
return false;
70+
}
71+
72+
public static Artifact ToArtifact (this Dependency dependency)
73+
{
74+
return new Artifact (dependency.GroupId.OrEmpty (), dependency.ArtifactId.OrEmpty ().OrEmpty (), dependency.Version.OrEmpty ());
75+
}
76+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System.Collections.Generic;
2+
using System.Collections.ObjectModel;
3+
using System.Xml.Linq;
4+
using Java.Interop.Tools.Maven.Models;
5+
6+
namespace Java.Interop.Tools.Maven.Extensions;
7+
8+
class PropertyStack
9+
{
10+
// Why go to this trouble?
11+
// A property can be specified in both a child POM and its parent POM.
12+
// Even if the property is being consumed in the parent POM, the property in
13+
// the child POM takes precedence.
14+
readonly List<List<KeyValuePair<string, string>>> stack = new ();
15+
16+
public void Push (ModelProperties? properties)
17+
{
18+
// We add a new list to the stack, even if it's empty, so that the Pop works later
19+
var list = new List<KeyValuePair<string, string>> ();
20+
21+
if (properties?.Any is Collection<XElement> props)
22+
foreach (var prop in props)
23+
list.Add (new KeyValuePair<string, string> (prop.Name.LocalName, prop.Value));
24+
25+
stack.Add (list);
26+
}
27+
28+
public void Pop ()
29+
{
30+
stack.RemoveAt (stack.Count - 1);
31+
}
32+
33+
public string Apply (string value)
34+
{
35+
foreach (var property_set in stack) {
36+
foreach (var prop in property_set)
37+
value = value.Replace ($"${{{prop.Key}}}", prop.Value);
38+
}
39+
40+
return value;
41+
}
42+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using Java.Interop.Tools.Maven.Models;
2+
3+
namespace Java.Interop.Tools.Maven;
4+
5+
public interface IPomResolver
6+
{
7+
Project ResolveRawProject (Artifact artifact);
8+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<LangVersion>11.0</LangVersion>
6+
<Nullable>enable</Nullable>
7+
<DefineConstants>INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
8+
<Nullable>enable</Nullable>
9+
<SignAssembly>true</SignAssembly>
10+
<AssemblyOriginatorKeyFile>..\..\product.snk</AssemblyOriginatorKeyFile>
11+
</PropertyGroup>
12+
13+
<Import Project="..\..\TargetFrameworkDependentValues.props" />
14+
15+
<PropertyGroup>
16+
<OutputPath>$(UtilityOutputFullPath)</OutputPath>
17+
</PropertyGroup>
18+
19+
<ItemGroup>
20+
<Compile Include="..\utils\NullableAttributes.cs" />
21+
</ItemGroup>
22+
23+
<ItemGroup>
24+
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
25+
</ItemGroup>
26+
27+
</Project>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
4+
namespace Java.Interop.Tools.Maven.Models;
5+
6+
public class Artifact
7+
{
8+
public string GroupId { get; }
9+
10+
public string Id { get; }
11+
12+
public string Version { get; }
13+
14+
public Artifact (string groupId, string artifactId, string version)
15+
{
16+
Id = artifactId;
17+
GroupId = groupId;
18+
Version = version;
19+
}
20+
21+
public static Artifact Parse (string value)
22+
{
23+
if (TryParse (value, out var artifact))
24+
return artifact;
25+
26+
throw new ArgumentException ($"Invalid artifact format: {value}");
27+
}
28+
29+
public static bool TryParse (string value, [NotNullWhen (true)]out Artifact? artifact)
30+
{
31+
artifact = null;
32+
33+
var parts = value.Split (':');
34+
35+
if (parts.Length != 3)
36+
return false;
37+
38+
artifact = new Artifact (parts [0], parts [1], parts [2]);
39+
40+
return true;
41+
}
42+
43+
// This is a "well-known" format we use, it should not be changed.
44+
public override string ToString () => $"{GroupId}:{Id}:{Version}";
45+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
using System.IO;
3+
using System.Xml;
4+
using System.Xml.Serialization;
5+
using Java.Interop.Tools.Maven.Extensions;
6+
7+
namespace Java.Interop.Tools.Maven.Models;
8+
9+
public partial class Project
10+
{
11+
public static Project Parse (Stream stream)
12+
{
13+
Project? result = null;
14+
15+
var serializer = new XmlSerializer (typeof (Project));
16+
17+
using (var sr = new StreamReader (stream))
18+
result = (Project) serializer.Deserialize (new XmlTextReader (sr) {
19+
Namespaces = false,
20+
});
21+
22+
return result;
23+
}
24+
25+
public static Project ParseXml (string xml)
26+
{
27+
Project? result = null;
28+
29+
var serializer = new XmlSerializer (typeof (Project));
30+
31+
using (var sr = new StringReader (xml))
32+
result = (Project) serializer.Deserialize (new XmlTextReader (sr) {
33+
Namespaces = false,
34+
});
35+
36+
return result;
37+
}
38+
39+
public bool TryGetParentPomArtifact ([NotNullWhen (true)] out Artifact? parent)
40+
{
41+
parent = null;
42+
43+
if (Parent is not null) {
44+
parent = new Artifact (Parent.GroupId.OrEmpty (), Parent.ArtifactId.OrEmpty (), Parent.Version.OrEmpty ());
45+
return true;
46+
}
47+
48+
return false;
49+
}
50+
51+
public override string ToString () => $"{GroupId}:{ArtifactId}:{Version}";
52+
53+
public string ToXml ()
54+
{
55+
var serializer = new XmlSerializer (typeof (Project));
56+
57+
using (var sw = new StringWriter ()) {
58+
serializer.Serialize (sw, this);
59+
return sw.ToString ();
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)