@startuml
package com.iluwatar.abstractdocument.domain.enums {
  enum Property {
    + MODEL {static}
    + PARTS {static}
    + PRICE {static}
    + TYPE {static}
    + valueOf(name : String) : Property {static}
    + values() : Property[] {static}
  }
}
package com.iluwatar.abstractdocument.domain {
  class Car {
    + Car(properties : Map<String, Object>)
  }
  interface HasModel {
    + getModel() : Optional<String>
  }
  interface HasParts {
    + getParts() : Stream<Part>
  }
  interface HasPrice {
    + getPrice() : Optional<Number>
  }
  interface HasType {
    + getType() : Optional<String>
  }
  class Part {
    + Part(properties : Map<String, Object>)
  }
}
package com.iluwatar.abstractdocument {
  abstract class AbstractDocument {
    - properties : Map<String, Object>
    # AbstractDocument(properties : Map<String, Object>)
    + children(key : String, constructor : Function<Map<String, Object>, T>) : Stream<T>
    + get(key : String) : Object
    + put(key : String, value : Object)
    + toString() : String
  }
  class App {
    - LOGGER : Logger {static}
    + App()
    + main(args : String[]) {static}
  }
  interface Document {
    + children(String, Function<Map<String, Object>, T>) : Stream<T> {abstract}
    + get(String) : Object {abstract}
    + put(String, Object) {abstract}
  }
}
AbstractDocument ..|> Document 
Car ..|> HasModel 
Car ..|> HasPrice 
Car ..|> HasParts 
Car --|> AbstractDocument 
HasModel --|> Document 
HasParts --|> Document 
HasPrice --|> Document 
HasType --|> Document 
Part ..|> HasType 
Part ..|> HasModel 
Part ..|> HasPrice 
Part --|> AbstractDocument 
@enduml