All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.touk.nussknacker.engine.definition.component.ComponentDefinitionWithImplementation.scala Maven / Gradle / Ivy

The newest version!
package pl.touk.nussknacker.engine.definition.component

import pl.touk.nussknacker.engine.api.component.Component._
import pl.touk.nussknacker.engine.api.component.ComponentType.ComponentType
import pl.touk.nussknacker.engine.api.component._
import pl.touk.nussknacker.engine.api.definition.WithExplicitTypesToExtract
import pl.touk.nussknacker.engine.api.typed.typing.TypingResult
import pl.touk.nussknacker.engine.modelconfig.ComponentsUiConfig

// This class represents component's definition and implementation. It is used on the designer side for definitions
// served to the FE and for validations. It is used on the runtime side for component's runtime execution and for stubbing.
// Implementing component is in hte implementation field. It should be rarely used - instead, we should extract information
// into definition. Runtime logic should be mainly used via implementationInvoker which can be transformed
// (e.g.) for purpose of stubbing.
trait ComponentDefinitionWithImplementation extends ObjectOperatingOnTypes {

  def implementationInvoker: ComponentImplementationInvoker

  // For purpose of transforming (e.g.) stubbing of the implementation
  def withImplementationInvoker(invoker: ComponentImplementationInvoker): ComponentDefinitionWithImplementation

  def component: Component

  def componentTypeSpecificData: ComponentTypeSpecificData

  // This field is used as a part of identifier so it is important that it should be stable.
  // Currently it is used also for a label presented at the toolbox palette but we should probably extract another
  // field (e.g. label) that will be in a more human friendly format`- see Parameter.name vs Parameter.label
  def name: String

  final def componentType: ComponentType = componentTypeSpecificData.componentType

  final def id: ComponentId = ComponentId(componentType, name)

  protected def uiDefinition: ComponentUiDefinition

  final def designerWideId: DesignerWideComponentId = uiDefinition.designerWideId

  final def componentGroup: ComponentGroupName = uiDefinition.componentGroup

  final def originalGroupName: ComponentGroupName = uiDefinition.originalGroupName

  final def icon: String = uiDefinition.icon

  final def docsUrl: Option[String] = uiDefinition.docsUrl

  override final def definedTypes: List[TypingResult] = {
    val fromExplicitTypes = component match {
      case explicit: WithExplicitTypesToExtract => explicit.typesToExtract
      case _                                    => Nil
    }
    typesFromStaticDefinition ++ fromExplicitTypes
  }

  protected def typesFromStaticDefinition: List[TypingResult]

  def allowedProcessingModes: AllowedProcessingModes = component.allowedProcessingModes

}

trait ObjectOperatingOnTypes {

  def definedTypes: List[TypingResult]

}

final case class ComponentUiDefinition(
    originalGroupName: ComponentGroupName,
    componentGroup: ComponentGroupName,
    icon: String,
    docsUrl: Option[String],
    designerWideId: DesignerWideComponentId
)

object ComponentDefinitionWithImplementation {

  def forList(
      components: List[ComponentDefinition],
      additionalConfigs: ComponentsUiConfig,
      determineDesignerWideId: ComponentId => DesignerWideComponentId,
      additionalConfigsFromProvider: Map[DesignerWideComponentId, ComponentAdditionalConfig]
  ): List[ComponentDefinitionWithImplementation] = {
    components.flatMap(
      ComponentDefinitionExtractor.extract(_, additionalConfigs, determineDesignerWideId, additionalConfigsFromProvider)
    )
  }

  /*  This method is mainly for the tests purpose. It doesn't take into an account:
   *    - additionalConfigs from the model configuration
   *    - additionalConfigsFromProvider provided by AdditionalUIConfigProvider
   */
  def withEmptyConfig(name: String, component: Component): ComponentDefinitionWithImplementation = {
    ComponentDefinitionExtractor
      .extract(
        name,
        component,
        ComponentConfig.zero,
        ComponentsUiConfig.Empty,
        id => DesignerWideComponentId(id.toString),
        Map.empty
      )
      .getOrElse(
        throw new IllegalStateException(
          s"Cannot extract component definition for $name (and component type: ${component.getClass.getName})"
        )
      )
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy