@startuml asa.m2

skinparam groupInheritance 2

abstract class Configuration {}

note top of Configuration : Configuration represent a system with all\ncomponents and connectors

Configuration o-[thickness=2]- "0..*" Component : components
Configuration *-[thickness=2]- "0..*" Binding : bindings
Configuration *-[thickness=2]- "0..*" Attachment : attachments

interface Contract {}

note left of Contract : Contract represent one or more\nports and services provided,\nrepresent also dependencies\n(ports and services)\nof this contracts

Contract *-[thickness=2]- "0..*" Service  : servicesRequired
Contract *-[thickness=2]- "0..*" Port : portsRequired
Contract -[thickness=2]-|> "1..*" Service : servicesProvided
Contract *-[thickness=2]- "1..*" Port : portsProvided

interface Port<Data> {
    listen(Observer<Data> observer)
    send(Data data)
}

note bottom of Port : Port represent node can be listened\nfor some data if Port is used for input\nor node can be receive data if Port is used for output\n(Both is possible if port is used by two Components :\nproductor and consommator for example)

interface Service {}

/'
TODO : Represent Service with methods and
extracts implements of Service outside of
Contract

Like this for example :
interface Service {
    signatures : List<Signature<Input, Output>>
}

interface Signature<Input, Output> {
    input : Input
    output : Output
}

interface ServiceImplementation {}

interface ServiceImplementationWithInputAndOutput<Input, Output> {
    call(Input input) : Output output
}

ServiceImplementationWithInputAndOutput --|> ServiceImplementation

interface ServiceImplementationWithInput<Output> {
    call() : Output output
}

ServiceImplementationWithInput --|> ServiceImplementation

class SingleComponent {
    servicesImplementations : Map<Signature<Input, Output>, ServiceImplementation>
}
'/

note bottom of Service : Service represent some\nfunctionality offer or\nrequired by Component

abstract class Component {}

note top of Component : Component represent a software entity\nimplements one or more Contract

Contract "0..*" <|-[thickness=2]- Component : implements

class SingleComponent {}

note top of SingleComponent : Single component represent\nsingle composant implements one or\nmore Contract

Component <|-[thickness=2]- SingleComponent

class CompositeComponent {}

note top of CompositeComponent : Composite component represents a configuration\nof a set of components, attachments and bindings\nthat can be used as a component,\nthat implements one or more Contract\n(like a Facade pattern)

Component <|-[thickness=2]- CompositeComponent
Configuration <|-[thickness=2]- CompositeComponent

abstract class Connector<From, To> {
    transform(From initialData) : To transformedData
}

note top of Connector : Connector represent transformation\nmethod for convertion from\nFrom type to To type

Connector <|-[thickness=2]- SimpleConnector

class SimpleConnector<From, To> {

}

note top of SimpleConnector : Simple Connector represent single\nConnector with dedicated\ntransformation method

Connector <|-[thickness=2]- CompositeConnector
Configuration <|-[thickness=2]- CompositeConnector

class CompositeConnector<From, To> {
    
}

note top of CompositeConnector : Composite connector represents a configuration\nof a set of components, attachments and bindings\nthat can be used as a connector\n(like a Facade pattern)

class Attachment<From, To> {}

note left of Attachment : Attachment listen on input port and\nfor each data received, Attachment use\ntransform method of connector and\nsend result to output

Attachment o-[thickness=2]- "1" Port : input
Attachment o-[thickness=2]- "1" Port : output
Attachment o-[thickness=2]- "1" Connector : connector

class Binding<From, To> {}

note top of Binding : Binding represent direct redirection\nbetween input Port and output Port\nwithout transformation

Binding o-[thickness=2]- "1" Port : input
Binding o-[thickness=2]- "1" Port : output

@enduml