/*
* 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.runtime.source;
import static org.mule.runtime.module.extension.internal.ExtensionProperties.SOURCE_CALLBACK_CONTEXT_PARAM;
import org.mule.runtime.api.meta.model.ExtensionModel;
import org.mule.runtime.api.meta.model.parameter.ParameterGroupModel;
import org.mule.runtime.api.meta.model.source.SourceModel;
import org.mule.runtime.core.api.Event;
import org.mule.runtime.core.api.MuleContext;
import org.mule.runtime.extension.api.runtime.ConfigurationInstance;
import org.mule.runtime.extension.api.runtime.operation.ExecutionContext;
import org.mule.runtime.extension.api.runtime.source.Source;
import org.mule.runtime.extension.api.runtime.source.SourceCallbackContext;
import org.mule.runtime.module.extension.internal.loader.java.property.SourceCallbackModelProperty;
import org.mule.runtime.module.extension.internal.runtime.DefaultExecutionContext;
import org.mule.runtime.module.extension.internal.runtime.ExecutionContextAdapter;
import org.mule.runtime.module.extension.internal.runtime.execution.ReflectiveMethodComponentExecutor;
import com.google.common.collect.ImmutableList;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* Implementation of {@link SourceCallbackExecutor} which uses reflection to execute the callback through a {@link Method}
*
* @since 4.0
*/
class ReflectiveSourceCallbackExecutor implements SourceCallbackExecutor {
private final ExtensionModel extensionModel;
private final Optional<ConfigurationInstance> configurationInstance;
private final SourceModel sourceModel;
private final MuleContext muleContext;
private final ReflectiveMethodComponentExecutor<SourceModel> executor;
/**
* Creates a new instance
*
* @param extensionModel the {@link ExtensionModel} of the owning component
* @param configurationInstance an {@link Optional} {@link ConfigurationInstance} in case the component requires a config
* @param sourceModel the model of the {@code source}
* @param source a {@link Source} instance
* @param method the method to be executed
* @param muleContext the current {@link MuleContext}
* @param sourceCallbackModel
*/
public ReflectiveSourceCallbackExecutor(ExtensionModel extensionModel,
Optional<ConfigurationInstance> configurationInstance,
SourceModel sourceModel,
Object source,
Method method,
MuleContext muleContext,
SourceCallbackModelProperty sourceCallbackModel) {
this.extensionModel = extensionModel;
this.configurationInstance = configurationInstance;
this.sourceModel = sourceModel;
this.muleContext = muleContext;
executor = new ReflectiveMethodComponentExecutor<>(getAllGroups(sourceModel, method, sourceCallbackModel), method, source);
}
/**
* {@inheritDoc}
*/
@Override
public Object execute(Event event, Map<String, Object> parameters, SourceCallbackContext context) throws Exception {
return executor.execute(createExecutionContext(event, parameters, context));
}
private ExecutionContext<SourceModel> createExecutionContext(Event event, Map<String, Object> parameters,
SourceCallbackContext callbackContext) {
ExecutionContextAdapter<SourceModel> executionContext = new DefaultExecutionContext<>(extensionModel,
configurationInstance,
parameters,
sourceModel,
event,
muleContext);
executionContext.setVariable(SOURCE_CALLBACK_CONTEXT_PARAM, callbackContext);
return executionContext;
}
private List<ParameterGroupModel> getAllGroups(SourceModel model, Method method,
SourceCallbackModelProperty sourceCallbackModel) {
List<ParameterGroupModel> callbackParameters = sourceCallbackModel.getOnSuccessMethod().filter(method::equals)
.map(m -> sourceModel.getSuccessCallback().get().getParameterGroupModels())
.orElseGet(() -> sourceModel.getErrorCallback().get().getParameterGroupModels());
return ImmutableList.<ParameterGroupModel>builder()
.addAll(model.getParameterGroupModels())
.addAll(callbackParameters).build();
}
}