/* * 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.config.spring.dsl.spring; import static java.util.Optional.empty; import static java.util.Optional.ofNullable; import static org.mule.runtime.config.spring.dsl.model.ApplicationModel.FLOW_IDENTIFIER; import static org.mule.runtime.config.spring.dsl.model.ApplicationModel.SUBFLOW_IDENTIFIER; import org.mule.runtime.api.component.TypedComponentIdentifier; import org.mule.runtime.api.meta.AnnotatedObject; import org.mule.runtime.config.spring.dsl.model.ComponentModel; import org.mule.runtime.core.api.processor.InterceptingMessageProcessor; import org.mule.runtime.core.api.processor.MessageRouter; import org.mule.runtime.core.api.processor.Processor; import org.mule.runtime.core.api.routing.OutboundRouter; import org.mule.runtime.core.api.routing.SelectiveRouter; import org.mule.runtime.core.api.source.MessageSource; import org.mule.runtime.core.exception.ErrorHandler; import org.mule.runtime.core.exception.TemplateOnErrorHandler; import org.mule.runtime.core.routing.AbstractSelectiveRouter; import org.mule.runtime.core.source.scheduler.DefaultSchedulerMessageSource; import java.util.HashMap; import java.util.Map; import java.util.Optional; import javax.xml.namespace.QName; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; public class ComponentModelHelper { /** * Resolves the {@link org.mule.runtime.api.component.TypedComponentIdentifier.ComponentType} from a {@link ComponentModel}. * * @param componentModel a {@link ComponentModel} that represents a component in the configuration. * @return the componentModel type. */ public static TypedComponentIdentifier.ComponentType resolveComponentType(ComponentModel componentModel) { if (isMessageSource(componentModel)) { return TypedComponentIdentifier.ComponentType.SOURCE; } else if (isErrorHandler(componentModel)) { return TypedComponentIdentifier.ComponentType.ERROR_HANDLER; } else if (isTemplateOnErrorHandler(componentModel)) { return TypedComponentIdentifier.ComponentType.ON_ERROR; } else if (isFlow(componentModel)) { return TypedComponentIdentifier.ComponentType.FLOW; } else if (isProcessor(componentModel)) { if (isInterceptingProcessor(componentModel)) { return TypedComponentIdentifier.ComponentType.INTERCEPTING; } else if (isRouterProcessor(componentModel)) { return TypedComponentIdentifier.ComponentType.ROUTER; } else { return TypedComponentIdentifier.ComponentType.PROCESSOR; } } return TypedComponentIdentifier.ComponentType.UNKNOWN; } public static boolean isAnnotatedObject(ComponentModel componentModel) { return isOfType(componentModel, AnnotatedObject.class); } private static boolean isRouterProcessor(ComponentModel componentModel) { return isOfType(componentModel, OutboundRouter.class) || isOfType(componentModel, SelectiveRouter.class) || isOfType(componentModel, MessageRouter.class); } private static boolean isInterceptingProcessor(ComponentModel componentModel) { return isOfType(componentModel, InterceptingMessageProcessor.class); } public static boolean isProcessor(ComponentModel componentModel) { if (componentModel.getIdentifier().getName().equals("flow-ref")) { // this condition is required until flow-ref is migrated to the new parsing mechanism. return true; } return isOfType(componentModel, Processor.class) || isOfType(componentModel, InterceptingMessageProcessor.class); } public static boolean isMessageSource(ComponentModel componentModel) { return isOfType(componentModel, MessageSource.class); } public static boolean isErrorHandler(ComponentModel componentModel) { return isOfType(componentModel, ErrorHandler.class); } public static boolean isPoll(ComponentModel componentModel) { return isOfType(componentModel, DefaultSchedulerMessageSource.class); } public static boolean isTemplateOnErrorHandler(ComponentModel componentModel) { return isOfType(componentModel, TemplateOnErrorHandler.class); } public static boolean isFlow(ComponentModel componentModel) { return componentModel.getIdentifier().equals(FLOW_IDENTIFIER); } public static boolean isSubflow(ComponentModel componentModel) { return componentModel.getIdentifier().equals(SUBFLOW_IDENTIFIER); } private static boolean isOfType(ComponentModel componentModel, Class type) { Class<?> componentModelType = componentModel.getType(); if (componentModelType == null) { return false; } return CommonBeanDefinitionCreator.areMatchingTypes(type, componentModelType); } public static void addAnnotation(QName annotationKey, Object annotationValue, ComponentModel componentModel) { // TODO MULE-10970 - remove condition once everything is AnnotatedObject. if (!ComponentModelHelper.isAnnotatedObject(componentModel) && !componentModel.getIdentifier().getName().equals("flow-ref")) { return; } BeanDefinition beanDefinition = componentModel.getBeanDefinition(); if (beanDefinition == null) { // This is the case of components that are references return; } PropertyValue propertyValue = beanDefinition.getPropertyValues().getPropertyValue(AnnotatedObject.PROPERTY_NAME); Map<QName, Object> annotations; if (propertyValue == null) { annotations = new HashMap<>(); propertyValue = new PropertyValue(AnnotatedObject.PROPERTY_NAME, annotations); componentModel.getBeanDefinition().getPropertyValues().addPropertyValue(propertyValue); } else { annotations = (Map<QName, Object>) propertyValue.getValue(); } annotations.put(annotationKey, annotationValue); } public static <T> Optional<T> getAnnotation(QName annotationKey, ComponentModel componentModel) { if (componentModel.getBeanDefinition() == null) { return empty(); } PropertyValue propertyValue = componentModel.getBeanDefinition().getPropertyValues().getPropertyValue(AnnotatedObject.PROPERTY_NAME); Map<QName, Object> annotations; if (propertyValue == null) { return empty(); } else { annotations = (Map<QName, Object>) propertyValue.getValue(); return ofNullable((T) annotations.get(annotationKey)); } } public static boolean isRouter(ComponentModel componentModel) { return isOfType(componentModel, MessageRouter.class) || isOfType(componentModel, AbstractSelectiveRouter.class); } }