/*
* Copyright 2016 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.transform;
import com.google.common.collect.Lists;
import org.gradle.api.Action;
import org.gradle.api.ActionConfiguration;
import org.gradle.api.artifacts.transform.ArtifactTransform;
import org.gradle.api.artifacts.transform.VariantTransform;
import org.gradle.api.artifacts.transform.VariantTransformConfigurationException;
import org.gradle.api.attributes.AttributeContainer;
import org.gradle.api.internal.DefaultActionConfiguration;
import org.gradle.api.internal.InstantiatorFactory;
import org.gradle.api.internal.artifacts.VariantTransformRegistry;
import org.gradle.api.internal.attributes.AttributeContainerInternal;
import org.gradle.api.internal.attributes.DefaultMutableAttributeContainer;
import org.gradle.api.internal.attributes.ImmutableAttributes;
import org.gradle.api.internal.attributes.ImmutableAttributesFactory;
import org.gradle.api.internal.changedetection.state.ValueSnapshotter;
import org.gradle.internal.classloader.ClassLoaderHierarchyHasher;
import java.util.List;
public class DefaultVariantTransformRegistry implements VariantTransformRegistry {
private static final Object[] NO_PARAMETERS = new Object[0];
private final List<Registration> transforms = Lists.newArrayList();
private final ImmutableAttributesFactory immutableAttributesFactory;
private final TransformedFileCache transformedFileCache;
private final ValueSnapshotter valueSnapshotter;
private final ClassLoaderHierarchyHasher classLoaderHierarchyHasher;
private final InstantiatorFactory instantiatorFactory;
public DefaultVariantTransformRegistry(InstantiatorFactory instantiatorFactory, ImmutableAttributesFactory immutableAttributesFactory, TransformedFileCache transformedFileCache, ValueSnapshotter valueSnapshotter, ClassLoaderHierarchyHasher classLoaderHierarchyHasher) {
this.instantiatorFactory = instantiatorFactory;
this.immutableAttributesFactory = immutableAttributesFactory;
this.transformedFileCache = transformedFileCache;
this.valueSnapshotter = valueSnapshotter;
this.classLoaderHierarchyHasher = classLoaderHierarchyHasher;
}
@Override
public void registerTransform(Action<? super VariantTransform> registrationAction) {
RecordingRegistration reg = instantiatorFactory.decorate().newInstance(RecordingRegistration.class, immutableAttributesFactory);
registrationAction.execute(reg);
if (reg.type == null) {
throw new VariantTransformConfigurationException("Could not register transform: an ArtifactTransform must be provided.");
}
if (reg.to.isEmpty()) {
throw new VariantTransformConfigurationException("Could not register transform: at least one 'to' attribute must be provided.");
}
if (reg.from.isEmpty()) {
throw new VariantTransformConfigurationException("Could not register transform: at least one 'from' attribute must be provided.");
}
if (!reg.from.keySet().containsAll(reg.to.keySet())) {
throw new VariantTransformConfigurationException("Could not register transform: each 'to' attribute must be included as a 'from' attribute.");
}
// TODO - should calculate this lazily
Object[] parameters = getTransformParameters(reg.config);
Registration registration = new DefaultVariantTransformRegistration(ImmutableAttributes.of(reg.from), ImmutableAttributes.of(reg.to), reg.type, parameters, transformedFileCache, valueSnapshotter, classLoaderHierarchyHasher, instantiatorFactory.inject());
transforms.add(registration);
}
public Iterable<Registration> getTransforms() {
return transforms;
}
private Object[] getTransformParameters(Action<? super ActionConfiguration> configAction) {
if (configAction == null) {
return NO_PARAMETERS;
}
ActionConfiguration config = new DefaultActionConfiguration();
configAction.execute(config);
return config.getParams();
}
public static class RecordingRegistration implements VariantTransform {
final AttributeContainerInternal from;
final AttributeContainerInternal to;
private Class<? extends ArtifactTransform> type;
private Action<? super ActionConfiguration> config;
public RecordingRegistration(ImmutableAttributesFactory immutableAttributesFactory) {
from = new DefaultMutableAttributeContainer(immutableAttributesFactory);
to = new DefaultMutableAttributeContainer(immutableAttributesFactory);
}
@Override
public AttributeContainer getFrom() {
return from;
}
@Override
public AttributeContainer getTo() {
return to;
}
@Override
public void artifactTransform(Class<? extends ArtifactTransform> type) {
artifactTransform(type, null);
}
@Override
public void artifactTransform(Class<? extends ArtifactTransform> type, Action<? super ActionConfiguration> config) {
if (this.type != null) {
throw new VariantTransformConfigurationException("Could not register transform: only one ArtifactTransform may be provided for registration.");
}
this.type = type;
this.config = config;
}
}
}