/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.runtime.module.extension.internal.util;
import static org.mule.runtime.api.meta.model.parameter.ParameterGroupModel.DEFAULT_GROUP_NAME;
import static org.mule.runtime.api.util.Preconditions.checkArgument;
import static org.springframework.util.ReflectionUtils.setField;
import org.mule.runtime.api.exception.MuleException;
import org.mule.runtime.api.meta.model.EnrichableModel;
import org.mule.runtime.api.meta.model.parameter.ParameterizedModel;
import org.mule.runtime.module.extension.internal.loader.ParameterGroupDescriptor;
import org.mule.runtime.module.extension.internal.loader.java.property.ParameterGroupModelProperty;
import org.mule.runtime.module.extension.internal.runtime.objectbuilder.ParameterGroupObjectBuilder;
import org.mule.runtime.module.extension.internal.runtime.resolver.ResolverSetResult;
import com.google.common.collect.ImmutableList;
import java.lang.reflect.Field;
import java.util.List;
/**
* An implementation of {@link ValueSetter} for parameter groups. Parameter groups are a set of parameters defined inside a Pojo
* in order to reference them as a group and avoid code repetition. The parameter groups are defined by applying the
* {@link org.mule.runtime.extension.api.annotation.param.ParameterGroup} annotation to a field.
* <p/>
* This {@link ValueSetter} knows how to map a {@link ResolverSetResult} to an object which acts as a group. Because group nesting
* is allowed, this class is a composite with a {@link #childSetters} collection.
*
* @since 3.7.0
*/
public final class GroupValueSetter implements ValueSetter {
/**
* Returns a {@link List} containing one {@link ValueSetter} instance per each
* {@link ParameterGroupDescriptor} defined in the
* {@link ParameterGroupModelProperty} extracted from the given {@code model}. If {@code model} does not contain such model
* property then an empty {@link List} is returned
*
* @param model a {@link EnrichableModel} instance presumed to have the {@link ParameterGroupModelProperty}
* @return a {@link List} with {@link ValueSetter} instances. May be empty but will never be {@code null}
*/
public static List<ValueSetter> settersFor(ParameterizedModel model) {
ImmutableList.Builder<ValueSetter> setters = ImmutableList.builder();
model.getParameterGroupModels().stream()
.filter(group -> !group.isShowInDsl())
.filter(group -> !group.getName().equals(DEFAULT_GROUP_NAME))
.forEach(group -> group.getModelProperty(ParameterGroupModelProperty.class).ifPresent(property -> {
if (property.getDescriptor().getContainer() instanceof Field) {
setters.add(new GroupValueSetter(property.getDescriptor()));
}
}));
return setters.build();
}
private final ParameterGroupDescriptor groupDescriptor;
private final Field container;
/**
* Creates a new instance that can set values defined in the given {@code group}
*
* @param groupDescriptor a {@link ParameterGroupDescriptor}
*/
public GroupValueSetter(ParameterGroupDescriptor groupDescriptor) {
this.groupDescriptor = groupDescriptor;
checkArgument(groupDescriptor.getContainer() instanceof Field, "Only field contained parameter groups are allowed");
container = (Field) groupDescriptor.getContainer();
}
@Override
public void set(Object target, ResolverSetResult result) throws MuleException {
container.setAccessible(true);
setField(container, target, new ParameterGroupObjectBuilder<>(groupDescriptor).build(result));
}
}