##// END OF EJS Templates
WIP stable versions CompileUnitsView, RoleProjectionsView, VariantSourcesExtension
cin -
r42:d67a4d2c04cf default
parent child
Show More
@@ -1,28 +1,102
1 1 package org.implab.gradle.variants;
2 2
3 3 import org.eclipse.jdt.annotation.NonNullByDefault;
4 import org.gradle.api.Action;
4 5 import org.gradle.api.Plugin;
5 6 import org.gradle.api.Project;
6 7 import org.implab.gradle.common.core.lang.Deferred;
8 import org.implab.gradle.common.sources.GenericSourceSet;
7 9 import org.implab.gradle.common.sources.SourcesPlugin;
10 import org.implab.gradle.variants.core.Layer;
11 import org.implab.gradle.variants.core.Variant;
8 12 import org.implab.gradle.variants.core.VariantsExtension;
13 import org.implab.gradle.variants.core.VariantsView;
14 import org.implab.gradle.variants.sources.CompileUnit;
15 import org.implab.gradle.variants.sources.CompileUnitsView;
16 import org.implab.gradle.variants.sources.RoleProjectionsView;
17 import org.implab.gradle.variants.sources.SourceSetMaterializer;
9 18 import org.implab.gradle.variants.sources.VariantSourcesContext;
10 19
11 20 @NonNullByDefault
12 21 public abstract class VariantSourcesPlugin implements Plugin<Project> {
13 22 @Override
14 23 public void apply(Project target) {
15 24 // Apply the main VariantsPlugin to ensure the core variant model is available.
16 25 target.getPlugins().apply(VariantsPlugin.class);
17 26 target.getPlugins().apply(SourcesPlugin.class);
18 27 // Access the VariantsExtension to configure variant sources.
19 28 var variantsExtension = target.getExtensions().getByType(VariantsExtension.class);
20 29 var objectFactory = target.getObjects();
21 30
22 31 var sources = SourcesPlugin.getSourcesExtension(target);
23 32
24 33 var deferred = new Deferred<VariantSourcesContext>();
25 34
35 variantsExtension.whenFinalized(variants -> {
36 var compileUnits = CompileUnitsView.of(variants);
37 var roleProjections = RoleProjectionsView.of(variants);
38
39 var context = new Context(variants, compileUnits, roleProjections);
40
41 deferred.resolve(context);
42 });
43
44 // var
45
26 46 }
27 47
48 private static class Context implements VariantSourcesContext {
49
50 private final VariantsView variantsView;
51 private final CompileUnitsView compileUnitsView;
52 private final RoleProjectionsView roleProjectionsView;
53
54 Context(VariantsView variantsView, CompileUnitsView compileUnitsView, RoleProjectionsView roleProjectionsView) {
55 this.variantsView = variantsView;
56 this.compileUnitsView = compileUnitsView;
57 this.roleProjectionsView = roleProjectionsView;
58 }
59
60 @Override
61 public VariantsView getVariants() {
62 return variantsView;
63 }
64
65 @Override
66 public CompileUnitsView getCompileUnits() {
67 return compileUnitsView;
68 }
69
70 @Override
71 public RoleProjectionsView getRoleProjections() {
72 return roleProjectionsView;
73 }
74
75 @Override
76 public SourceSetMaterializer getSourceSets() {
77 // TODO Auto-generated method stub
78 throw new UnsupportedOperationException("Unimplemented method 'getSourceSets'");
79 }
80
81 @Override
82 public void configureLayer(Layer layer, Action<? super GenericSourceSet> action) {
83 // TODO Auto-generated method stub
84 throw new UnsupportedOperationException("Unimplemented method 'configureLayer'");
85 }
86
87 @Override
88 public void configureVariant(Variant variant, Action<? super GenericSourceSet> action) {
89 // TODO Auto-generated method stub
90 throw new UnsupportedOperationException("Unimplemented method 'configureVariant'");
91 }
92
93 @Override
94 public void configureUnit(CompileUnit unit, Action<? super GenericSourceSet> action) {
95 // TODO Auto-generated method stub
96 throw new UnsupportedOperationException("Unimplemented method 'configureUnit'");
97 }
98
99 }
100
101
28 102 }
@@ -1,7 +1,12
1 package org.implab.gradle.variants.derived;
1 package org.implab.gradle.variants.sources;
2 2
3 3 import org.implab.gradle.variants.core.Layer;
4 4 import org.implab.gradle.variants.core.Variant;
5 import org.implab.gradle.variants.core.VariantsView.VariantRoleLayer;
5 6
6 7 public record CompileUnit(Variant variant, Layer layer) {
8
9 public static CompileUnit of(VariantRoleLayer entry) {
10 return new CompileUnit(entry.variant(), entry.layer());
11 }
7 12 }
@@ -1,32 +1,78
1 package org.implab.gradle.variants.derived;
1 package org.implab.gradle.variants.sources;
2 2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Objects;
3 6 import java.util.Optional;
4 7 import java.util.Set;
8 import java.util.stream.Collectors;
5 9
6 10 import org.eclipse.jdt.annotation.NonNullByDefault;
7 11 import org.implab.gradle.variants.core.Layer;
8 12 import org.implab.gradle.variants.core.Role;
9 13 import org.implab.gradle.variants.core.Variant;
14 import org.implab.gradle.variants.core.VariantsView;
15 import org.implab.gradle.variants.core.VariantsView.VariantRoleLayer;
10 16
11 17 @NonNullByDefault
12 public interface CompileUnitsView {
13 Set<CompileUnit> getUnits();
18 public final class CompileUnitsView {
19
20 private final VariantsView variants;
21 private final Map<Variant, Set<CompileUnit>> unitsByVariant = new HashMap<>();
22
23 private CompileUnitsView(VariantsView variants) {
24 this.variants = variants;
25 }
26
27 public Set<CompileUnit> getUnits() {
28 return variants.getEntries().stream()
29 .map(CompileUnit::of)
30 .collect(Collectors.toUnmodifiableSet());
31 }
32
33 public Set<CompileUnit> getUnitsForVariant(Variant variant) {
34 Objects.requireNonNull(variant, "Variant can't be null");
35
36 return unitsByVariant.computeIfAbsent(variant, key -> variants
37 .getEntriesForVariant(variant).stream()
38 .map(CompileUnit::of)
39 .collect(Collectors.toUnmodifiableSet()));
40 }
14 41
15 Set<CompileUnit> getUnitsForVariant(Variant variant);
42 public Optional<CompileUnit> findUnit(Variant variant, Layer layer) {
43 Objects.requireNonNull(variant, "Variant can't be null");
44 Objects.requireNonNull(layer, "Layer can't be null");
45
46 return getUnitsForVariant(variant).stream()
47 .filter(u -> u.layer().equals(layer))
48 .findAny();
49 }
50
51 public boolean contains(Variant variant, Layer layer) {
52 return findUnit(variant, layer).isPresent();
53 }
16 54
17 Optional<CompileUnit> findUnit(Variant variant, Layer layer);
55 /**
56 * In which logical roles this compile unit participates.
57 */
18 58
19 default CompileUnit getUnit(Variant variant, Layer layer) {
59 public Set<Role> getRoles(CompileUnit unit) {
60 Objects.requireNonNull(unit, "Compile unit can't be null");
61 return variants.getEntriesForVariant(unit.variant()).stream()
62 .filter(entry -> entry.layer().equals(unit.layer()))
63 .map(VariantRoleLayer::role)
64 .collect(Collectors.toUnmodifiableSet());
65 }
66
67 public CompileUnit getUnit(Variant variant, Layer layer) {
20 68 return findUnit(variant, layer)
21 69 .orElseThrow(() -> new IllegalArgumentException(
22 70 "Compile unit for variant '" + variant.getName()
23 71 + "' and layer '" + layer.getName() + "' not found"));
24 72 }
25 73
26 boolean contains(Variant variant, Layer layer);
27
28 /**
29 * In which logical roles this compile unit participates.
30 */
31 Set<Role> getRoles(CompileUnit unit);
74 public static CompileUnitsView of(VariantsView variantsView) {
75 Objects.requireNonNull(variantsView, "variantsView can't be null");
76 return new CompileUnitsView(variantsView);
77 }
32 78 } No newline at end of file
@@ -1,7 +1,12
1 package org.implab.gradle.variants.derived;
1 package org.implab.gradle.variants.sources;
2 2
3 3 import org.implab.gradle.variants.core.Role;
4 4 import org.implab.gradle.variants.core.Variant;
5 import org.implab.gradle.variants.core.VariantsView.VariantRoleLayer;
5 6
6 7 public record RoleProjection(Variant variant, Role role) {
8
9 public static RoleProjection of(VariantRoleLayer entry) {
10 return new RoleProjection(entry.variant(), entry.role());
11 }
7 12 }
@@ -1,35 +1,83
1 package org.implab.gradle.variants.derived;
1 package org.implab.gradle.variants.sources;
2 2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Objects;
3 6 import java.util.Optional;
4 7 import java.util.Set;
8 import java.util.stream.Collectors;
5 9
6 10 import org.implab.gradle.variants.core.Layer;
7 11 import org.implab.gradle.variants.core.Role;
8 12 import org.implab.gradle.variants.core.Variant;
13 import org.implab.gradle.variants.core.VariantsView;
9 14
10 public interface RoleProjectionsView {
11 Set<RoleProjection> getProjections();
15 public final class RoleProjectionsView {
16 private final VariantsView variants;
17
18 private final Map<Variant, Set<RoleProjection>> projectionsByVariant = new HashMap<>();
19
20 private RoleProjectionsView(VariantsView variants) {
21 this.variants = variants;
22 }
12 23
13 Set<RoleProjection> getProjectionsForVariant(Variant variant);
24 public Set<RoleProjection> getProjections() {
25 return variants.getEntries().stream()
26 .map(RoleProjection::of)
27 .collect(Collectors.toUnmodifiableSet());
28 }
29
30 public Set<RoleProjection> getProjectionsForVariant(Variant variant) {
31 Objects.requireNonNull(variant, "Variant can't be null");
32 return projectionsByVariant.computeIfAbsent(variant, key -> variants
33 .getEntriesForVariant(variant).stream()
34 .map(RoleProjection::of)
35 .collect(Collectors.toUnmodifiableSet()));
36 }
14 37
15 Set<RoleProjection> getProjectionsForRole(Role role);
38 public Set<RoleProjection> getProjectionsForRole(Role role) {
39 Objects.requireNonNull(role, "Role can't be null");
40 return variants.getEntriesForRole(role).stream()
41 .map(RoleProjection::of)
42 .collect(Collectors.toUnmodifiableSet());
43 }
16 44
17 Optional<RoleProjection> findProjection(Variant variant, Role role);
45 public Optional<RoleProjection> findProjection(Variant variant, Role role) {
46 Objects.requireNonNull(variant, "Variant can't be null");
47 Objects.requireNonNull(role, "Role can't be null");
48 return variants.getEntriesForVariant(variant).stream()
49 .filter(entry -> entry.role().equals(role))
50 .map(RoleProjection::of)
51 .findAny();
52 }
18 53
19 default RoleProjection getProjection(Variant variant, Role role) {
54 public boolean contains(Variant variant, Role role) {
55 return findProjection(variant, role).isPresent();
56 }
57
58 public Set<CompileUnit> getUnits(RoleProjection projection) {
59 Objects.requireNonNull(projection, "Role projection can't be null");
60 return variants.getEntriesForVariant(projection.variant()).stream()
61 .filter(entry -> entry.role().equals(projection.role()))
62 .map(CompileUnit::of)
63 .collect(Collectors.toUnmodifiableSet());
64
65 }
66
67 public RoleProjection getProjection(Variant variant, Role role) {
20 68 return findProjection(variant, role)
21 69 .orElseThrow(() -> new IllegalArgumentException(
22 70 "Role projection for variant '" + variant.getName()
23 71 + "' and role '" + role.getName() + "' not found"));
24 72 }
25 73
26 boolean contains(Variant variant, Role role);
27
28 Set<CompileUnit> getUnits(RoleProjection projection);
29
30 default Set<Layer> getLayers(RoleProjection projection) {
74 public Set<Layer> getLayers(RoleProjection projection) {
31 75 return getUnits(projection).stream()
32 76 .map(CompileUnit::layer)
33 77 .collect(java.util.stream.Collectors.toUnmodifiableSet());
34 78 }
79
80 public static RoleProjectionsView of(VariantsView variantsView) {
81 return new RoleProjectionsView(variantsView);
82 }
35 83 } No newline at end of file
@@ -1,18 +1,17
1 1 package org.implab.gradle.variants.sources;
2 2
3 3 import org.gradle.api.NamedDomainObjectProvider;
4 4 import org.implab.gradle.common.sources.GenericSourceSet;
5 import org.implab.gradle.variants.derived.CompileUnit;
6 5
7 6 /**
8 7 * Materializes symbolic source set names into actual GenericSourceSet
9 8 * instances.
10 9 */
11 10 public interface SourceSetMaterializer {
12 11 /**
13 12 * Returns a lazy provider for the source set corresponding to the compile unit.
14 13 *
15 14 * The provider is stable and cached per compile unit.
16 15 */
17 16 NamedDomainObjectProvider<GenericSourceSet> getSourceSet(CompileUnit unit);
18 17 } No newline at end of file
@@ -1,50 +1,51
1 1 package org.implab.gradle.variants.sources;
2 2
3 import java.util.Set;
4
5 3 import org.gradle.api.Action;
6 import org.gradle.api.NamedDomainObjectCollection;
7 4 import org.implab.gradle.common.sources.GenericSourceSet;
8 5 import org.implab.gradle.variants.core.Layer;
6 import org.implab.gradle.variants.core.Variant;
9 7 import org.implab.gradle.variants.core.VariantsView;
10 import org.implab.gradle.variants.derived.CompileUnitsView;
11 import org.implab.gradle.variants.derived.RoleProjectionsView;
12 8
13 9 /**
14 10 * Registry of symbolic source set names produced by sources projection.
15 11 *
16 12 * Identity in this registry is the GenericSourceSet name.
17 13 */
18 14 public interface VariantSourcesContext {
19 15
20 16 /**
21 17 * Finalized core model.
22 18 */
23 19 VariantsView getVariants();
24 20
25 21 /**
26 22 * Derived compile-side view.
27 23 */
28 24 CompileUnitsView getCompileUnits();
29 25
30 26 /**
31 27 * Derived role-side view.
32 28 */
33 29 RoleProjectionsView getRoleProjections();
34 30
35 31 /**
36 32 * Lazy source set provider service.
37 33 */
38 34 SourceSetMaterializer getSourceSets();
39 35
40 36 /**
41 37 * Configures all GenericSourceSets produced from the given layer.
42 38 *
43 39 * The action is applied:
44 40 * - to already materialized source sets of this layer
45 41 * - to all future source sets of this layer
46 42 *
47 43 * Actions are applied in registration order.
48 44 */
49 45 void configureLayer(Layer layer, Action<? super GenericSourceSet> action);
46
47 void configureVariant(Variant variant, Action<? super GenericSourceSet> action);
48
49 void configureUnit(CompileUnit unit, Action<? super GenericSourceSet> action);
50
50 51 } No newline at end of file
@@ -1,22 +1,93
1 1 package org.implab.gradle.variants.sources;
2 2
3 import java.util.Objects;
4 import java.util.function.Predicate;
5
6 import org.eclipse.jdt.annotation.NonNullByDefault;
3 7 import org.gradle.api.Action;
8 import org.gradle.api.InvalidUserDataException;
9 import org.gradle.api.Named;
4 10 import org.implab.gradle.common.core.lang.Closures;
11 import org.implab.gradle.common.core.lang.Strings;
12 import org.implab.gradle.common.sources.GenericSourceSet;
13 import org.implab.gradle.variants.core.Layer;
14 import org.implab.gradle.variants.core.Variant;
15 import org.implab.gradle.variants.core.VariantsView;
5 16
6 17 import groovy.lang.Closure;
7 18
19 @NonNullByDefault
8 20 public interface VariantSourcesExtension {
9 21
22 default void layer(String layerName, Action<? super GenericSourceSet> action) {
23 // protect external DSL
24 Strings.argumentNotNullOrBlank(layerName, "layerName");
25 Objects.requireNonNull(action, "action can't be null");
26
27 whenFinalized(ctx -> ctx.configureLayer(resolveLayer(ctx.getVariants(), layerName), action));
28 }
29
30 default void layer(String layerName, Closure<?> closure) {
31 layer(layerName, Closures.action(closure));
32 }
33
34 default void variant(String variantName, Action<? super GenericSourceSet> action) {
35 Strings.argumentNotNullOrBlank(variantName, "variantName");
36 Objects.requireNonNull(action, "action can't be null");
37
38 whenFinalized(ctx -> ctx.configureVariant(resolveVariant(ctx.getVariants(), variantName), action));
39 }
40
41 default void variant(String variantName, Closure<?> closure) {
42 variant(variantName, Closures.action(closure));
43 }
44
45 default void unit(String variantName, String layerName, Action<? super GenericSourceSet> action) {
46 Strings.argumentNotNullOrBlank(layerName, "layerName");
47 Strings.argumentNotNullOrBlank(variantName, "variantName");
48 Objects.requireNonNull(action, "action can't be null");
49
50 whenFinalized(ctx -> ctx.configureUnit(resolveCompileUnit(ctx, variantName, layerName), action));
51 }
52
10 53 /**
11 54 * Invoked when finalized variants-derived source context becomes available.
12 55 *
13 56 * Replayable:
14 * - if called before variants finalization, action is queued
15 * - if called after variants finalization, action is invoked immediately
57 * <ul>
58 * <li>if called before variants finalization, action is queued
59 * <li>if called after variants finalization, action is invoked immediately
60 * </ul>
16 61 */
17 62 void whenFinalized(Action<? super VariantSourcesContext> action);
18 63
19 64 default void whenFinalized(Closure<?> closure) {
20 65 whenFinalized(Closures.action(closure));
21 66 }
67
68 private static Layer resolveLayer(VariantsView variants, String name) {
69 return variants.getLayers().stream()
70 .filter(named(name))
71 .findAny()
72 .orElseThrow(() -> new IllegalArgumentException("Layer '" + name + "' isn't declared"));
73 }
74
75 private static Variant resolveVariant(VariantsView variants, String name) {
76 return variants.getVariants().stream()
77 .filter(named(name))
78 .findAny()
79 .orElseThrow(() -> new IllegalArgumentException("Variant '" + name + "' is't declared"));
80 }
81
82 private static CompileUnit resolveCompileUnit(VariantSourcesContext ctx, String variantName, String layerName) {
83 return ctx.getCompileUnits().findUnit(
84 resolveVariant(ctx.getVariants(), variantName),
85 resolveLayer(ctx.getVariants(), layerName))
86 .orElseThrow(() -> new InvalidUserDataException(
87 "The CompileUnit isn't declared for variant '" + variantName + "', layer '" + layerName + "'"));
88 }
89
90 private static Predicate<Named> named(String name) {
91 return named -> named.getName().equals(name);
92 }
22 93 } No newline at end of file
@@ -1,39 +1,48
1 1 package org.implab.gradle.variants.sources.internal;
2 2
3 3 import java.util.ArrayList;
4 4 import java.util.LinkedHashMap;
5 5 import java.util.List;
6 6 import java.util.Map;
7 import java.util.Objects;
8 7
8 import org.eclipse.jdt.annotation.NonNullByDefault;
9 9 import org.gradle.api.Action;
10 10 import org.implab.gradle.common.sources.GenericSourceSet;
11 11 import org.implab.gradle.variants.core.Layer;
12 import org.implab.gradle.variants.derived.CompileUnit;
12 import org.implab.gradle.variants.core.Variant;
13 import org.implab.gradle.variants.sources.CompileUnit;
13 14
15 @NonNullByDefault
14 16 public class DefaultLayerConfigurationRegistry implements LayerConfigurationRegistry {
15 17 private final Map<Layer, List<Action<? super GenericSourceSet>>> actionsByLayer = new LinkedHashMap<>();
18 private final Map<Variant, List<Action<? super GenericSourceSet>>> actionsByVariant = new LinkedHashMap<>();
19 private final Map<CompileUnit, List<Action<? super GenericSourceSet>>> actionsByUnit = new LinkedHashMap<>();
16 20
17 @Override
18 public void add(Layer layer, Action<? super GenericSourceSet> action) {
19 Objects.requireNonNull(layer, "layer can't be null");
20 Objects.requireNonNull(action, "action can't be null");
21 public void addLayerAction(Layer layer, Action<? super GenericSourceSet> action) {
21 22 actionsByLayer.computeIfAbsent(layer, key -> new ArrayList<>()).add(action);
22 23 }
23 24
25 public void addVariantAction(Variant variant, Action<? super GenericSourceSet> action) {
26 actionsByVariant.computeIfAbsent(variant, key -> new ArrayList<>()).add(action);
27 }
28
29 public void addUnitAction(CompileUnit unit, Action<? super GenericSourceSet> action) {
30 actionsByUnit.computeIfAbsent(unit, key -> new ArrayList<>()).add(action);
31 }
32
24 33 @Override
25 34 public void applyLayer(Layer layer, GenericSourceSet sourceSet) {
26 35 var actions = actionsByLayer.get(layer);
27 36 if (actions == null) {
28 37 return;
29 38 }
30 39 for (var action : actions) {
31 40 action.execute(sourceSet);
32 41 }
33 42 }
34 43
35 44 @Override
36 45 public void applyUnit(CompileUnit unit, GenericSourceSet sourceSet) {
37 46 applyLayer(unit.layer(), sourceSet);
38 47 }
39 48 }
@@ -1,15 +1,15
1 1 package org.implab.gradle.variants.sources.internal;
2 2
3 3 import org.gradle.api.Action;
4 4 import org.implab.gradle.common.sources.GenericSourceSet;
5 5 import org.implab.gradle.variants.core.Layer;
6 import org.implab.gradle.variants.derived.CompileUnit;
6 import org.implab.gradle.variants.sources.CompileUnit;
7 7
8 8 public interface LayerConfigurationRegistry {
9 9
10 void add(Layer layer, Action<? super GenericSourceSet> action);
10 void addLayerAction(Layer layer, Action<? super GenericSourceSet> action);
11 11
12 12 void applyLayer(Layer layer, GenericSourceSet sourceSet);
13 13
14 14 void applyUnit(CompileUnit unit, GenericSourceSet sourceSet);
15 15 }
General Comments 0
You need to be logged in to leave comments. Login now