diff --git a/subprojects/core-api/src/main/java/org/gradle/api/artifacts/MinimalExternalModuleDependency.java b/subprojects/core-api/src/main/java/org/gradle/api/artifacts/MinimalExternalModuleDependency.java index f3566ef2fd6a..cf00aa8861ba 100644 --- a/subprojects/core-api/src/main/java/org/gradle/api/artifacts/MinimalExternalModuleDependency.java +++ b/subprojects/core-api/src/main/java/org/gradle/api/artifacts/MinimalExternalModuleDependency.java @@ -26,4 +26,10 @@ public interface MinimalExternalModuleDependency extends ExternalModuleDependency { ModuleIdentifier getModule(); VersionConstraint getVersionConstraint(); + + /** + * {@inheritDoc} + */ + @Override + MinimalExternalModuleDependency copy(); } diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dependencies/AbstractModuleDependency.java b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dependencies/AbstractModuleDependency.java index bd72dffb9326..3dea85d27466 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dependencies/AbstractModuleDependency.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/artifacts/dependencies/AbstractModuleDependency.java @@ -275,10 +275,14 @@ public void setCapabilityNotationParser(NotationParser capab this.capabilityNotationParser = capabilityNotationParser; } - protected ImmutableAttributesFactory getAttributesFactory() { + public ImmutableAttributesFactory getAttributesFactory() { return attributesFactory; } + public NotationParser getCapabilityNotationParser() { + return capabilityNotationParser; + } + private void setAttributes(AttributeContainerInternal attributes) { this.attributes = attributes; } diff --git a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy index ee7f681cdfe0..407f973ea7cb 100644 --- a/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy +++ b/subprojects/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/api/ArtifactDeclarationIntegrationTest.groovy @@ -209,7 +209,7 @@ task checkArtifacts { } task jar {} } - + project(':b') { dependencies { compile project(':a') @@ -218,7 +218,7 @@ task checkArtifacts { task checkArtifacts { inputs.files configurations.compile doLast { - configurations.compile.resolvedConfiguration.resolvedArtifacts.forEach { println it } + configurations.compile.resolvedConfiguration.resolvedArtifacts.forEach { println it } } } } @@ -247,7 +247,7 @@ task checkArtifacts { } task jar {} } - + project(':b') { dependencies { compile project(':a') @@ -256,7 +256,7 @@ task checkArtifacts { task checkArtifacts { inputs.files configurations.compile doLast { - assert configurations.compile.resolvedConfiguration.resolvedArtifacts.each { println it } + assert configurations.compile.resolvedConfiguration.resolvedArtifacts.each { println it } } } } @@ -289,7 +289,7 @@ task checkArtifacts { } task classes {} } - + project(':b') { dependencies { compile project(':a') @@ -298,7 +298,7 @@ task checkArtifacts { task checkArtifacts { inputs.files configurations.compile doLast { - assert configurations.compile.resolvedConfiguration.resolvedArtifacts.each { println it } + assert configurations.compile.resolvedConfiguration.resolvedArtifacts.each { println it } } } } @@ -506,4 +506,53 @@ task checkArtifacts { result.assertTasksExecutedInOrder(":a:checkArtifacts", ":a:jar", ":b:checkArtifacts") } + def 'artifacts are copied when declaring dependency on existing version catalog dependency with artifact'() { + given: + buildFile << """ + configurations { + implementation + destination1 + destination2 + } + + dependencies { + implementation(libs.test) { + artifact { + classifier = "alternative" + } + } + } + + task copyAndPrintDependencies { + configurations.implementation.dependencies.each { + project.dependencies.add("destination1", it) + configurations.destination2.dependencies.add(it) + } + + doLast { + configurations.implementation.dependencies.each { + println("implementation " + it + " " + it.artifacts*.classifier) + } + configurations.destination1.dependencies.each { + println("destination1 " + it + " " + it.artifacts*.classifier) + } + configurations.destination2.dependencies.each { + println("destination2 " + it + " " + it.artifacts*.classifier) + } + } + } + """ + file("gradle/libs.versions.toml") << """[libraries] +test = { module = 'org:test', version = '1.0' } +""" + + when: + succeeds "copyAndPrintDependencies" + + then: + outputContains("""implementation org:test:1.0 [alternative] +destination1 org:test:1.0 [alternative] +destination2 org:test:1.0 [alternative]""") + } + } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DependencyManagementBuildScopeServices.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DependencyManagementBuildScopeServices.java index 60f269101415..ac98101a459c 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DependencyManagementBuildScopeServices.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/DependencyManagementBuildScopeServices.java @@ -21,7 +21,6 @@ import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Sets; import org.gradle.StartParameter; -import org.gradle.api.capabilities.Capability; import org.gradle.api.internal.ClassPathRegistry; import org.gradle.api.internal.CollectionCallbackActionDecorator; import org.gradle.api.internal.DocumentationRegistry; @@ -30,6 +29,7 @@ import org.gradle.api.internal.artifacts.component.ComponentIdentifierFactory; import org.gradle.api.internal.artifacts.component.DefaultComponentIdentifierFactory; import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParserFactory; import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactoryInternal; import org.gradle.api.internal.artifacts.ivyservice.ArtifactCacheLockingManager; @@ -215,7 +215,6 @@ import org.gradle.internal.service.ServiceRegistry; import org.gradle.internal.snapshot.ValueSnapshot; import org.gradle.internal.snapshot.ValueSnapshotter; -import org.gradle.internal.typeconversion.NotationParser; import org.gradle.internal.vfs.VirtualFileSystem; import org.gradle.util.internal.BuildCommencedTimeProvider; import org.gradle.util.internal.SimpleMapInterner; @@ -274,11 +273,15 @@ VersionComparator createVersionComparator() { return new DefaultVersionComparator(); } + CapabilityNotationParser createCapabilityNotationParser() { + return new CapabilityNotationParserFactory(false).create(); + } + DefaultProjectDependencyFactory createProjectDependencyFactory( Instantiator instantiator, StartParameter startParameter, - ImmutableAttributesFactory attributesFactory) { - NotationParser capabilityNotationParser = new CapabilityNotationParserFactory(false).create(); + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser) { return new DefaultProjectDependencyFactory(instantiator, startParameter.isBuildProjectDependencies(), capabilityNotationParser, attributesFactory); } @@ -290,13 +293,13 @@ DependencyFactoryInternal createDependencyFactory( FileCollectionFactory fileCollectionFactory, RuntimeShadedJarFactory runtimeShadedJarFactory, ImmutableAttributesFactory attributesFactory, - SimpleMapInterner stringInterner) { - NotationParser capabilityNotationParser = new CapabilityNotationParserFactory(false).create(); + SimpleMapInterner stringInterner, + CapabilityNotationParser capabilityNotationParser) { ProjectDependencyFactory projectDependencyFactory = new ProjectDependencyFactory(factory); return new DefaultDependencyFactory( instantiator, - DependencyNotationParser.create(instantiator, factory, classPathRegistry, fileCollectionFactory, runtimeShadedJarFactory, currentGradleInstallation, stringInterner, attributesFactory, capabilityNotationParser), + DependencyNotationParser.create(instantiator, factory, classPathRegistry, fileCollectionFactory, runtimeShadedJarFactory, currentGradleInstallation, stringInterner), DependencyConstraintNotationParser.parser(instantiator, factory, stringInterner, attributesFactory), new ClientModuleNotationParserFactory(instantiator, stringInterner).create(), capabilityNotationParser, projectDependencyFactory, @@ -677,8 +680,10 @@ DependenciesAccessors createDependenciesAccessorGenerator(ClassPathRegistry regi ExecutionEngine executionEngine, FeaturePreviews featurePreviews, FileCollectionFactory fileCollectionFactory, - InputFingerprinter inputFingerprinter) { - return new DefaultDependenciesAccessors(registry, workspace, factory, featurePreviews, executionEngine, fileCollectionFactory, inputFingerprinter); + InputFingerprinter inputFingerprinter, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser) { + return new DefaultDependenciesAccessors(registry, workspace, factory, featurePreviews, executionEngine, fileCollectionFactory, inputFingerprinter, attributesFactory, capabilityNotationParser); } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultExternalModuleDependency.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultExternalModuleDependency.java index 568858d08f1a..72ff9177baff 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultExternalModuleDependency.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultExternalModuleDependency.java @@ -36,7 +36,7 @@ public DefaultExternalModuleDependency(ModuleIdentifier id, MutableVersionConstr } @Override - public DefaultExternalModuleDependency copy() { + public ExternalModuleDependency copy() { DefaultExternalModuleDependency copiedModuleDependency = new DefaultExternalModuleDependency(getGroup(), getName(), getVersion(), getTargetConfiguration()); copyTo(copiedModuleDependency); return copiedModuleDependency; diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependency.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependency.java index 1222bfdedf38..15f1563cd19d 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependency.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependency.java @@ -15,13 +15,12 @@ */ package org.gradle.api.internal.artifacts.dependencies; -import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.ModuleIdentifier; import org.gradle.api.artifacts.MutableVersionConstraint; import java.io.Serializable; -public class DefaultMinimalDependency extends DefaultExternalModuleDependency implements MinimalExternalModuleDependency, Serializable { +public class DefaultMinimalDependency extends DefaultExternalModuleDependency implements MinimalExternalModuleDependencyInternal, Serializable { public DefaultMinimalDependency(ModuleIdentifier module, MutableVersionConstraint versionConstraint) { super(module, versionConstraint); } @@ -41,6 +40,11 @@ protected void validateMutation(Object currentValue, Object newValue) { validateMutation(); } + @Override + public void copyTo(AbstractExternalModuleDependency target) { + super.copyTo(target); + } + // Intentionally changes to the mutable version. @Override public DefaultMutableMinimalDependency copy() { diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java index 77c00d044182..aaeb98f7393b 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMinimalDependencyVariant.java @@ -18,38 +18,92 @@ import org.gradle.api.Action; import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.ModuleDependencyCapabilitiesHandler; +import org.gradle.api.artifacts.ModuleIdentifier; +import org.gradle.api.artifacts.MutableVersionConstraint; import org.gradle.api.attributes.AttributeContainer; +import org.gradle.api.internal.artifacts.dsl.dependencies.ModuleFactoryHelper; import org.gradle.internal.Actions; +import org.gradle.util.internal.GUtil; import javax.annotation.Nullable; -public class DefaultMinimalDependencyVariant extends DefaultExternalModuleDependency implements MinimalExternalModuleDependency, DependencyVariant { - private final MinimalExternalModuleDependency delegate; - private final Action attributesMutator; - private final Action capabilitiesMutator; - private final String classifier; - private final String artifactType; +public class DefaultMinimalDependencyVariant extends DefaultExternalModuleDependency implements MinimalExternalModuleDependencyInternal, DependencyVariant { + private Action attributesMutator; + private Action capabilitiesMutator; + private String classifier; + private String artifactType; public DefaultMinimalDependencyVariant(MinimalExternalModuleDependency delegate, @Nullable Action attributesMutator, @Nullable Action capabilitiesMutator, @Nullable String classifier, - @Nullable String artifactType) { + @Nullable String artifactType + ) { super(delegate.getModule(), new DefaultMutableVersionConstraint(delegate.getVersionConstraint())); - this.delegate = delegate; - boolean delegateIsVariant = delegate instanceof DefaultMinimalDependencyVariant; - this.attributesMutator = delegateIsVariant ? Actions.composite(((DefaultMinimalDependencyVariant) delegate).attributesMutator, attributesMutator == null ? Actions.doNothing() : attributesMutator) : attributesMutator; - this.capabilitiesMutator = delegateIsVariant ? Actions.composite(((DefaultMinimalDependencyVariant) delegate).capabilitiesMutator, capabilitiesMutator == null ? Actions.doNothing() : capabilitiesMutator) : capabilitiesMutator; - if (classifier == null && delegateIsVariant) { - classifier = ((DefaultMinimalDependencyVariant) delegate).getClassifier(); - } - if (artifactType == null && delegateIsVariant) { - artifactType = ((DefaultMinimalDependencyVariant) delegate).getArtifactType(); + + attributesMutator = GUtil.elvis(attributesMutator, Actions.doNothing()); + capabilitiesMutator = GUtil.elvis(capabilitiesMutator, Actions.doNothing()); + + if (delegate instanceof DefaultMinimalDependencyVariant) { + this.attributesMutator = Actions.composite(((DefaultMinimalDependencyVariant) delegate).attributesMutator, attributesMutator); + this.capabilitiesMutator = Actions.composite(((DefaultMinimalDependencyVariant) delegate).capabilitiesMutator, capabilitiesMutator); + this.classifier = GUtil.elvis(classifier, ((DefaultMinimalDependencyVariant) delegate).getClassifier()); + this.artifactType = GUtil.elvis(classifier, ((DefaultMinimalDependencyVariant) delegate).getArtifactType()); + } else { + this.attributesMutator = attributesMutator; + this.capabilitiesMutator = capabilitiesMutator; + this.classifier = classifier; + this.artifactType = artifactType; } + + MinimalExternalModuleDependencyInternal internal = (MinimalExternalModuleDependencyInternal) delegate; + setAttributesFactory(internal.getAttributesFactory()); + setCapabilityNotationParser(internal.getCapabilityNotationParser()); + } + + private DefaultMinimalDependencyVariant( + ModuleIdentifier id, + MutableVersionConstraint versionConstraint, + Action attributesMutator, + Action capabilitiesMutator, + @Nullable String classifier, + @Nullable String artifactType + ) { + super(id, versionConstraint); + this.attributesMutator = attributesMutator; + this.capabilitiesMutator = capabilitiesMutator; this.classifier = classifier; this.artifactType = artifactType; } + @Override + public void copyTo(AbstractExternalModuleDependency target) { + super.copyTo(target); + if (target instanceof DefaultMinimalDependencyVariant) { + DefaultMinimalDependencyVariant depVariant = (DefaultMinimalDependencyVariant) target; + depVariant.attributesMutator = attributesMutator; + depVariant.capabilitiesMutator = capabilitiesMutator; + depVariant.classifier = classifier; + depVariant.artifactType = artifactType; + } else { + target.attributes(attributesMutator); + target.capabilities(capabilitiesMutator); + if (classifier != null || artifactType != null) { + ModuleFactoryHelper.addExplicitArtifactsIfDefined(target, artifactType, classifier); + } + } + } + + @Override + public MinimalExternalModuleDependency copy() { + DefaultMinimalDependencyVariant dependency = new DefaultMinimalDependencyVariant( + getModule(), new DefaultMutableVersionConstraint(getVersionConstraint()), + attributesMutator, capabilitiesMutator, classifier, artifactType + ); + copyTo(dependency); + return dependency; + } + @Override public void because(String reason) { validateMutation(); @@ -67,16 +121,12 @@ protected void validateMutation(Object currentValue, Object newValue) { @Override public void mutateAttributes(AttributeContainer attributes) { - if (attributesMutator!= null) { - attributesMutator.execute(attributes); - } + attributesMutator.execute(attributes); } @Override public void mutateCapabilities(ModuleDependencyCapabilitiesHandler capabilitiesHandler) { - if (capabilitiesMutator != null) { - capabilitiesMutator.execute(capabilitiesHandler); - } + capabilitiesMutator.execute(capabilitiesHandler); } @Nullable @@ -93,6 +143,11 @@ public String getArtifactType() { @Override public String toString() { - return delegate.toString(); + return "DefaultMinimalDependencyVariant{" + + ", attributesMutator=" + attributesMutator + + ", capabilitiesMutator=" + capabilitiesMutator + + ", classifier='" + classifier + '\'' + + ", artifactType='" + artifactType + '\'' + + "} " + super.toString(); } } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMutableMinimalDependency.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMutableMinimalDependency.java index c51481ede0a4..6ce58307d727 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMutableMinimalDependency.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/DefaultMutableMinimalDependency.java @@ -15,13 +15,12 @@ */ package org.gradle.api.internal.artifacts.dependencies; -import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.ModuleIdentifier; import org.gradle.api.artifacts.MutableVersionConstraint; import java.io.Serializable; -public class DefaultMutableMinimalDependency extends DefaultExternalModuleDependency implements MinimalExternalModuleDependency, Serializable { +public class DefaultMutableMinimalDependency extends DefaultExternalModuleDependency implements MinimalExternalModuleDependencyInternal, Serializable { public DefaultMutableMinimalDependency(ModuleIdentifier module, MutableVersionConstraint versionConstraint) { super(module, versionConstraint); } @@ -33,6 +32,11 @@ public DefaultMutableMinimalDependency copy() { return dependency; } + @Override + public void copyTo(AbstractExternalModuleDependency target) { + super.copyTo(target); + } + public String toString() { String versionConstraintAsString = getVersionConstraint().toString(); return versionConstraintAsString.isEmpty() diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java new file mode 100644 index 000000000000..73e7a1d53850 --- /dev/null +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dependencies/MinimalExternalModuleDependencyInternal.java @@ -0,0 +1,30 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.api.internal.artifacts.dependencies; + +import org.gradle.api.artifacts.MinimalExternalModuleDependency; +import org.gradle.api.capabilities.Capability; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; +import org.gradle.internal.typeconversion.NotationParser; + +public interface MinimalExternalModuleDependencyInternal extends MinimalExternalModuleDependency { + void copyTo(AbstractExternalModuleDependency target); + + ImmutableAttributesFactory getAttributesFactory(); + + NotationParser getCapabilityNotationParser(); +} diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParser.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParser.java new file mode 100644 index 000000000000..ecf18cb812d3 --- /dev/null +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParser.java @@ -0,0 +1,28 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.api.internal.artifacts.dsl; + +import org.gradle.api.capabilities.Capability; +import org.gradle.internal.typeconversion.NotationParser; + +/** + * A concrete type for a generic {@link NotationParser} that parses {@link Capability}s. + *

+ * This concrete type is necessary so that it can be injected into version catalog generated sources. + */ +public interface CapabilityNotationParser extends NotationParser { +} diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParserFactory.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParserFactory.java index dfb3a90817e4..77e4535137aa 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParserFactory.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/CapabilityNotationParserFactory.java @@ -25,14 +25,15 @@ import org.gradle.internal.typeconversion.MapNotationConverter; import org.gradle.internal.typeconversion.NotationParser; import org.gradle.internal.typeconversion.NotationParserBuilder; +import org.gradle.internal.typeconversion.TypeConversionException; import org.gradle.internal.typeconversion.TypedNotationConverter; import javax.annotation.Nonnull; import javax.annotation.Nullable; public class CapabilityNotationParserFactory implements Factory> { - private final static NotationParser STRICT_CONVERTER = createSingletonConverter(true); - private final static NotationParser LENIENT_CONVERTER = createSingletonConverter(false); + private final static CapabilityNotationParser STRICT_CONVERTER = createSingletonConverter(true); + private final static CapabilityNotationParser LENIENT_CONVERTER = createSingletonConverter(false); private final boolean versionIsRequired; @@ -40,16 +41,27 @@ public CapabilityNotationParserFactory(boolean versionIsRequired) { this.versionIsRequired = versionIsRequired; } - private static NotationParser createSingletonConverter(boolean strict) { - return NotationParserBuilder.toType(Capability.class) + private static CapabilityNotationParser createSingletonConverter(boolean strict) { + NotationParser parser = NotationParserBuilder.toType(Capability.class) .converter(new StringNotationParser(strict)) .converter(strict ? new StrictCapabilityMapNotationParser() : new LenientCapabilityMapNotationParser()) .toComposite(); + return new CapabilityNotationParser() { + @Override + public Capability parseNotation(Object notation) throws TypeConversionException { + return parser.parseNotation(notation); + } + + @Override + public void describe(DiagnosticsVisitor visitor) { + parser.describe(visitor); + } + }; } @Nonnull @Override - public NotationParser create() { + public CapabilityNotationParser create() { // Currently the converter is stateless, doesn't need any external context, so for performance we return a singleton return versionIsRequired ? STRICT_CONVERTER : LENIENT_CONVERTER; } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/AbstractExternalDependencyFactory.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/AbstractExternalDependencyFactory.java index 9e0539bbea5c..a661201b6d8b 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/AbstractExternalDependencyFactory.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/AbstractExternalDependencyFactory.java @@ -21,6 +21,8 @@ import org.gradle.api.internal.artifacts.ImmutableVersionConstraint; import org.gradle.api.internal.artifacts.dependencies.DefaultMinimalDependency; import org.gradle.api.internal.artifacts.dependencies.DefaultMutableVersionConstraint; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; @@ -28,13 +30,14 @@ import org.gradle.plugin.use.PluginDependency; import javax.inject.Inject; -import java.util.ArrayList; import java.util.stream.Collectors; public abstract class AbstractExternalDependencyFactory implements ExternalModuleDependencyFactory { protected final DefaultVersionCatalog config; protected final ProviderFactory providers; protected final ObjectFactory objects; + protected final ImmutableAttributesFactory attributesFactory; + protected final CapabilityNotationParser capabilityNotationParser; @SuppressWarnings("unused") public static abstract class SubDependencyFactory implements ExternalModuleDependencyFactory { @@ -54,11 +57,15 @@ public Provider create(String alias) { @Inject protected AbstractExternalDependencyFactory(DefaultVersionCatalog config, ProviderFactory providers, - ObjectFactory objects + ObjectFactory objects, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser ) { this.config = config; this.providers = providers; this.objects = objects; + this.attributesFactory = attributesFactory; + this.capabilityNotationParser = capabilityNotationParser; } @Override @@ -66,14 +73,17 @@ public Provider create(String alias) { return providers.of( DependencyValueSource.class, spec -> spec.getParameters().getDependencyData().set(config.getDependencyData(alias)) - ).map(AbstractExternalDependencyFactory::createMinimalDependency); + ).map(x -> createMinimalDependency(x, attributesFactory, capabilityNotationParser)); } - private static DefaultMinimalDependency createMinimalDependency(DependencyModel data) { + private static DefaultMinimalDependency createMinimalDependency(DependencyModel data, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { ImmutableVersionConstraint version = data.getVersion(); - return new DefaultMinimalDependency( + DefaultMinimalDependency result = new DefaultMinimalDependency( DefaultModuleIdentifier.newId(data.getGroup(), data.getName()), new DefaultMutableVersionConstraint(version) ); + result.setAttributesFactory(attributesFactory); + result.setCapabilityNotationParser(capabilityNotationParser); + return result; } public static class VersionFactory { @@ -118,11 +128,15 @@ public static class BundleFactory { protected final ProviderFactory providers; protected final DefaultVersionCatalog config; protected final ObjectFactory objects; + protected final ImmutableAttributesFactory attributesFactory; + protected final CapabilityNotationParser capabilityNotationParser; - public BundleFactory(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config) { + public BundleFactory(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { this.objects = objects; this.providers = providers; this.config = config; + this.attributesFactory = attributesFactory; + this.capabilityNotationParser = capabilityNotationParser; } protected Provider createBundle(String name) { @@ -134,13 +148,10 @@ protected Provider createBundle(String name) { params.getBundleName().set(name); }) ).map(dataList -> dataList.stream() - .map(AbstractExternalDependencyFactory::createMinimalDependency) - .collect(Collectors.toCollection(DefaultBundle::new)))); + .map(x -> createMinimalDependency(x, attributesFactory, capabilityNotationParser)) + .collect(Collectors.toCollection(DefaultExternalModuleDependencyBundle::new)))); return property; } - - private static class DefaultBundle extends ArrayList implements ExternalModuleDependencyBundle { - } } public static class PluginFactory { diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultDependenciesAccessors.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultDependenciesAccessors.java index abb9ac67afce..dbf4a18c3245 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultDependenciesAccessors.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultDependenciesAccessors.java @@ -30,7 +30,9 @@ import org.gradle.api.internal.FeaturePreviews; import org.gradle.api.internal.SettingsInternal; import org.gradle.api.internal.artifacts.DefaultProjectDependencyFactory; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; import org.gradle.api.internal.artifacts.dsl.dependencies.ProjectFinder; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.file.FileCollectionFactory; import org.gradle.api.internal.initialization.ClassLoaderScope; import org.gradle.api.internal.project.ProjectInternal; @@ -96,6 +98,9 @@ public class DefaultDependenciesAccessors implements DependenciesAccessors { private final ExecutionEngine engine; private final FileCollectionFactory fileCollectionFactory; private final InputFingerprinter inputFingerprinter; + private final ImmutableAttributesFactory attributesFactory; + private final CapabilityNotationParser capabilityNotationParser; + private final List models = Lists.newArrayList(); private final Map> factories = Maps.newHashMap(); @@ -110,7 +115,10 @@ public DefaultDependenciesAccessors(ClassPathRegistry registry, FeaturePreviews featurePreview, ExecutionEngine engine, FileCollectionFactory fileCollectionFactory, - InputFingerprinter inputFingerprinter) { + InputFingerprinter inputFingerprinter, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser + ) { this.classPath = registry.getClassPath("DEPENDENCIES-EXTENSION-COMPILER"); this.workspace = workspace; this.projectDependencyFactory = projectDependencyFactory; @@ -118,6 +126,8 @@ public DefaultDependenciesAccessors(ClassPathRegistry registry, this.engine = engine; this.fileCollectionFactory = fileCollectionFactory; this.inputFingerprinter = inputFingerprinter; + this.attributesFactory = attributesFactory; + this.capabilityNotationParser = capabilityNotationParser; } @Override @@ -239,7 +249,7 @@ public void createExtensions(ProjectInternal project) { } if (factory != null) { container.create(model.getName(), factory, model); - catalogs.put(model.getName(), new VersionCatalogView(model, providerFactory, project.getObjects())); + catalogs.put(model.getName(), new VersionCatalogView(model, providerFactory, project.getObjects(), attributesFactory, capabilityNotationParser)); } } } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalDependencyFactory.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalDependencyFactory.java index 8527b7911af9..5a341fbf8563 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalDependencyFactory.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalDependencyFactory.java @@ -16,13 +16,21 @@ package org.gradle.api.internal.catalog; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ProviderFactory; public class DefaultExternalDependencyFactory extends AbstractExternalDependencyFactory { - public DefaultExternalDependencyFactory(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects) { - super(config, providers, objects); + public DefaultExternalDependencyFactory( + DefaultVersionCatalog config, + ProviderFactory providers, + ObjectFactory objects, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser + ) { + super(config, providers, objects, attributesFactory, capabilityNotationParser); } } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalModuleDependencyBundle.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalModuleDependencyBundle.java new file mode 100644 index 000000000000..1df6feb68dc4 --- /dev/null +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultExternalModuleDependencyBundle.java @@ -0,0 +1,28 @@ +/* + * Copyright 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.api.internal.catalog; + +import org.gradle.api.artifacts.ExternalModuleDependencyBundle; +import org.gradle.api.artifacts.MinimalExternalModuleDependency; + +import java.util.ArrayList; + +/** + * Default implementation of {@link ExternalModuleDependencyBundle}. + */ +public class DefaultExternalModuleDependencyBundle extends ArrayList implements ExternalModuleDependencyBundle { +} diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/LibrariesSourceGenerator.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/LibrariesSourceGenerator.java index 6c871c5558d3..7d8e3ee34663 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/LibrariesSourceGenerator.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/LibrariesSourceGenerator.java @@ -23,6 +23,8 @@ import org.gradle.api.artifacts.ExternalModuleDependencyBundle; import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.MutableVersionConstraint; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.catalog.problems.VersionCatalogProblem; import org.gradle.api.internal.catalog.problems.VersionCatalogProblemId; import org.gradle.api.model.ObjectFactory; @@ -105,8 +107,8 @@ private void writeLibraryEntryPoint(String className, ClassNode librariesEntryPo writeSubAccessorFieldsOf(pluginsEntryPoint, AccessorKind.plugin); writeLn(); writeLn("@Inject"); - writeLn("public " + className + "(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects) {"); - writeLn(" super(config, providers, objects);"); + writeLn("public " + className + "(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) {"); + writeLn(" super(config, providers, objects, attributesFactory, capabilityNotationParser);"); writeLn("}"); writeLn(); writeLibraryAccessors(librariesEntryPoint); @@ -133,6 +135,8 @@ private void addImports() throws IOException { addImport(AbstractExternalDependencyFactory.class); addImport(DefaultVersionCatalog.class); addImport(Map.class); + addImport(ImmutableAttributesFactory.class); + addImport(CapabilityNotationParser.class); addImport(Inject.class); } @@ -176,7 +180,7 @@ private void writeBundleAccessorClass(ClassNode classNode) throws IOException { indent(() -> { writeSubAccessorFieldsOf(classNode, AccessorKind.bundle); writeLn(); - writeLn("public " + bundleClassName + "(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config) { super(objects, providers, config); }"); + writeLn("public " + bundleClassName + "(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { super(objects, providers, config, attributesFactory, capabilityNotationParser); }"); writeLn(); if (isProvider) { String path = classNode.getFullAlias(); @@ -610,7 +614,7 @@ public String toString() { private enum AccessorKind { library("libraries", "owner"), version("versions", "providers, config"), - bundle("bundles", "objects, providers, config"), + bundle("bundles", "objects, providers, config, attributesFactory, capabilityNotationParser"), plugin("plugins", "providers, config"); private final String description; diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/VersionCatalogView.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/VersionCatalogView.java index 37e06bd5cf57..af3bca9349b0 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/VersionCatalogView.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/VersionCatalogView.java @@ -20,6 +20,8 @@ import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.VersionCatalog; import org.gradle.api.artifacts.VersionConstraint; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory.BundleFactory; import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory.PluginFactory; import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory.VersionFactory; @@ -29,7 +31,6 @@ import org.gradle.internal.deprecation.DeprecationLogger; import org.gradle.plugin.use.PluginDependency; -import javax.inject.Inject; import java.util.List; import java.util.Optional; @@ -39,15 +40,21 @@ public class VersionCatalogView implements VersionCatalog { private final DefaultVersionCatalog config; private final ProviderFactory providerFactory; - private final ExternalModuleDependencyFactory dependencyFactory; - private final ObjectFactory objects; - @Inject - public VersionCatalogView(DefaultVersionCatalog config, ProviderFactory providerFactory, ObjectFactory objects) { + private final ExternalModuleDependencyFactory dependencyFactory; + private final BundleFactory bundleFactory; + + public VersionCatalogView( + DefaultVersionCatalog config, + ProviderFactory providerFactory, + ObjectFactory objects, + ImmutableAttributesFactory attributesFactory, + CapabilityNotationParser capabilityNotationParser + ) { this.config = config; this.providerFactory = providerFactory; - this.objects = objects; - this.dependencyFactory = new DefaultExternalDependencyFactory(config, providerFactory, objects); + this.dependencyFactory = new DefaultExternalDependencyFactory(config, providerFactory, objects, attributesFactory, capabilityNotationParser); + this.bundleFactory = new BundleFactory(objects, providerFactory, config, attributesFactory, capabilityNotationParser); } @Override @@ -74,7 +81,7 @@ public final Optional> findLibrary(Str public final Optional> findBundle(String alias) { String normalizedBundle = normalize(alias); if (config.getBundleAliases().contains(normalizedBundle)) { - return Optional.of(new BundleFactory(objects, providerFactory, config).createBundle(normalizedBundle)); + return Optional.of(bundleFactory.createBundle(normalizedBundle)); } return Optional.empty(); } diff --git a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java index e7e7bde38980..76f6061c161f 100644 --- a/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java +++ b/subprojects/dependency-management/src/main/java/org/gradle/api/internal/notations/DependencyNotationParser.java @@ -23,16 +23,13 @@ import org.gradle.api.artifacts.FileCollectionDependency; import org.gradle.api.artifacts.MinimalExternalModuleDependency; import org.gradle.api.artifacts.ProjectDependency; -import org.gradle.api.capabilities.Capability; import org.gradle.api.file.FileCollection; import org.gradle.api.internal.ClassPathRegistry; import org.gradle.api.internal.artifacts.DefaultProjectDependencyFactory; import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency; import org.gradle.api.internal.artifacts.dependencies.DefaultMutableMinimalDependency; -import org.gradle.api.internal.artifacts.dependencies.DependencyVariant; +import org.gradle.api.internal.artifacts.dependencies.MinimalExternalModuleDependencyInternal; import org.gradle.api.internal.artifacts.dsl.dependencies.DependencyFactoryInternal; -import org.gradle.api.internal.artifacts.dsl.dependencies.ModuleFactoryHelper; -import org.gradle.api.internal.attributes.ImmutableAttributesFactory; import org.gradle.api.internal.file.FileCollectionFactory; import org.gradle.api.internal.runtimeshaded.RuntimeShadedJarFactory; import org.gradle.internal.exceptions.DiagnosticsVisitor; @@ -55,13 +52,11 @@ public static DependencyNotationParser create(Instantiator instantiator, FileCollectionFactory fileCollectionFactory, RuntimeShadedJarFactory runtimeShadedJarFactory, CurrentGradleInstallation currentGradleInstallation, - Interner stringInterner, - ImmutableAttributesFactory attributesFactory, - NotationParser capabilityNotationParser) { + Interner stringInterner) { NotationConverter stringNotationConverter = new DependencyStringNotationConverter<>(instantiator, DefaultExternalModuleDependency.class, stringInterner); NotationConverter minimalExternalDependencyNotationConverter = - new MinimalExternalDependencyNotationConverter(instantiator, attributesFactory, capabilityNotationParser); + new MinimalExternalDependencyNotationConverter(instantiator); MapNotationConverter mapNotationConverter = new DependencyMapNotationConverter<>(instantiator, DefaultExternalModuleDependency.class); NotationConverter filesNotationConverter = @@ -138,37 +133,22 @@ public NotationParser getNotationParser() { private static class MinimalExternalDependencyNotationConverter implements NotationConverter { private final Instantiator instantiator; - private final ImmutableAttributesFactory attributesFactory; - private final NotationParser capabilityNotationParser; - public MinimalExternalDependencyNotationConverter(Instantiator instantiator, ImmutableAttributesFactory attributesFactory, NotationParser capabilityNotationParser) { + public MinimalExternalDependencyNotationConverter(Instantiator instantiator) { this.instantiator = instantiator; - this.attributesFactory = attributesFactory; - this.capabilityNotationParser = capabilityNotationParser; } @Override public void convert(MinimalExternalModuleDependency notation, NotationConvertResult result) throws TypeConversionException { DefaultMutableMinimalDependency moduleDependency = instantiator.newInstance(DefaultMutableMinimalDependency.class, notation.getModule(), notation.getVersionConstraint()); - if (notation instanceof DependencyVariant) { - moduleDependency.setAttributesFactory(attributesFactory); - moduleDependency.setCapabilityNotationParser(capabilityNotationParser); - DependencyVariant dependencyVariant = (DependencyVariant) notation; - moduleDependency.attributes(dependencyVariant::mutateAttributes); - moduleDependency.capabilities(dependencyVariant::mutateCapabilities); - String classifier = dependencyVariant.getClassifier(); - String artifactType = dependencyVariant.getArtifactType(); - if (classifier != null || artifactType != null) { - ModuleFactoryHelper.addExplicitArtifactsIfDefined(moduleDependency, artifactType, classifier); - } - } + MinimalExternalModuleDependencyInternal internal = (MinimalExternalModuleDependencyInternal) notation; + internal.copyTo(moduleDependency); result.converted(moduleDependency); } @Override public void describe(DiagnosticsVisitor visitor) { } - - } + } diff --git a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/catalog/LibrariesSourceGeneratorTest.groovy b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/catalog/LibrariesSourceGeneratorTest.groovy index cb5a07971cef..ef1647ad0409 100644 --- a/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/catalog/LibrariesSourceGeneratorTest.groovy +++ b/subprojects/dependency-management/src/test/groovy/org/gradle/api/internal/catalog/LibrariesSourceGeneratorTest.groovy @@ -22,6 +22,9 @@ import org.gradle.api.InvalidUserDataException import org.gradle.api.internal.ClassPathRegistry import org.gradle.api.internal.DefaultClassPathProvider import org.gradle.api.internal.DefaultClassPathRegistry +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParserFactory +import org.gradle.api.internal.attributes.ImmutableAttributesFactory import org.gradle.api.internal.catalog.problems.VersionCatalogErrorMessages import org.gradle.api.internal.catalog.problems.VersionCatalogProblemId import org.gradle.api.internal.catalog.problems.VersionCatalogProblemTestFor @@ -40,6 +43,7 @@ import org.gradle.internal.management.VersionCatalogBuilderInternal import org.gradle.internal.service.scopes.Scopes import org.gradle.process.ExecOperations import org.gradle.test.fixtures.file.TestNameTestDirectoryProvider +import org.gradle.util.AttributeTestUtil import org.gradle.util.TestUtil import org.junit.Rule import spock.lang.Issue @@ -60,6 +64,8 @@ class LibrariesSourceGeneratorTest extends Specification implements VersionCatal private GeneratedSource sources final ObjectFactory objects = TestUtil.objectFactory() + final ImmutableAttributesFactory attributesFactory = AttributeTestUtil.attributesFactory() + final CapabilityNotationParser capabilityNotationParser = new CapabilityNotationParserFactory(false).create() final ProviderFactory providerFactory = new DefaultProviderFactory( new DefaultValueSourceProviderFactory( new DefaultListenerManager(Scopes.Build), @@ -406,7 +412,7 @@ ${nameClash { noIntro().kind('dependency bundles').inConflict('one.cool', 'oneCo def cl = new URLClassLoader([dstDir.toURI().toURL()] as URL[], this.class.classLoader) factory = cl.loadClass("org.test.$className") assert factory - factory.newInstance(model, providerFactory, objects) + factory.newInstance(model, providerFactory, objects, attributesFactory, capabilityNotationParser) } }