Advertisement
Guest User

Untitled

a guest
Jul 13th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 9.56 KB | None | 0 0
  1. package ex09
  2.  
  3. import java.time.LocalDateTime
  4. import java.time.ZoneOffset
  5. import java.time.format.DateTimeFormatter
  6. import java.time.Duration
  7. import java.time.Instant
  8. import java.time.temporal.ChronoUnit
  9.  
  10. import de.tudarmstadt.stg.sedc.annotations.builder.ConcreteBuilder
  11. import de.tudarmstadt.stg.sedc.annotations.composite.{ChildManagement, Composite, Leaf}
  12. import de.tudarmstadt.stg.sedc.annotations.decorator.{ConcreteComponent, ConcreteDecorator}
  13. import de.tudarmstadt.stg.sedc.annotations.visitor.{ConcreteElement, ConcreteVisitor, Element}
  14.  
  15. @Element
  16. trait Visitable {
  17.     def accept(visitor: Visitor)
  18. }
  19.  
  20. @de.tudarmstadt.stg.sedc.annotations.visitor.Visitor
  21. trait Visitor {
  22.     def visit(simpleTask: SimpleTask)
  23.     def visit(dependentTask: DependentTask)
  24.     def visit(billableTask: BillableTask)
  25.     def visit(project: Project)
  26. }
  27.  
  28. @ConcreteVisitor
  29. class InvoiceVisitor extends Visitor {
  30.     var totalInvoice: String = ""
  31.  
  32.     override def visit(simpleTask: SimpleTask): Unit = {}
  33.  
  34.     override def visit(dependentTask: DependentTask): Unit = {}
  35.  
  36.     override def visit(billableTask: BillableTask): Unit = {
  37.         totalInvoice.concat(billableTask.description + ": " + billableTask.rate * billableTask.duration.get(ChronoUnit.HOURS))
  38.     }
  39.  
  40.     override def visit(project: Project): Unit = {
  41.         for(task: Task <- project.list)
  42.             task match {
  43.                 case a: BillableTask => visit(a)
  44.                 case _ => ()
  45.             }
  46.     }
  47.  
  48.     def getInvoice: String = totalInvoice
  49. }
  50.  
  51. @ConcreteVisitor
  52. class ValidationVisitor extends Visitor {
  53.     var consistent = true
  54.  
  55.     override def visit(simpleTask: SimpleTask): Unit = {}
  56.  
  57.     override def visit(dependentTask: DependentTask): Unit = {
  58.         if(dependentTask.aTask.dueDate.get.compareTo(dependentTask.anotherTask.dueDate.get) >= 0)
  59.             consistent = false
  60.     }
  61.  
  62.     override def visit(billableTask: BillableTask): Unit = {}
  63.  
  64.     override def visit(project: Project): Unit = {
  65.         for(task: Task <- project.list)
  66.             task match {
  67.                 case a: DependentTask => visit(a)
  68.                 case _ => ()
  69.             }
  70.     }
  71.  
  72.     def isConsistent: Boolean = {false}
  73. }
  74.  
  75. @ConcreteVisitor
  76. class NextDeadlineVisitor extends Visitor {
  77.     override def visit(simpleTask: SimpleTask): Unit = {}
  78.  
  79.     override def visit(dependentTask: DependentTask): Unit = {}
  80.  
  81.     override def visit(billableTask: BillableTask): Unit = {}
  82.  
  83.     override def visit(project: Project): Unit = {}
  84.  
  85.     def getNextDeadline: Instant = Instant.MAX
  86. }
  87.  
  88. trait Task extends Visitable{
  89.     def description: String
  90.  
  91.     def duration: Duration
  92.  
  93.     def dueDate: Option[Instant]
  94.  
  95.     def completionDate: Option[Instant]
  96.  
  97.     def startDate: Option[Instant]
  98.  
  99.     def context: Option[String]
  100.  
  101.     def priority: Option[Char]
  102.  
  103.     def markDone(): Unit
  104.  
  105.     def addTime(duration: Duration): Unit
  106. }
  107.  
  108.  
  109. trait OutputFormat {
  110.  
  111.     def format(visitables: List[Visitable]): String
  112.  
  113.     protected def printInstantAsDate(instant: Instant): String = {
  114.         val datetime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC)
  115.         DateTimeFormatter.ofPattern("yyyy-MM-dd").format(datetime)
  116.     }
  117. }
  118.  
  119. trait Export[T] {
  120.     def result: T
  121. }
  122.  
  123. @ConcreteComponent
  124. @Leaf
  125. @ConcreteElement
  126. case class SimpleTask(description: String, dueDate: Option[Instant], context: Option[String], priority: Option[Char], startDate: Option[Instant]) extends Task {
  127.     var _completeDate: Option[Instant] = None
  128.  
  129.     override def duration: Duration = Duration.ZERO
  130.  
  131.     override def completionDate: Option[Instant] = _completeDate
  132.  
  133.     override def markDone(): Unit = _completeDate = Some(Instant.now)
  134.  
  135.     override def addTime(duration: Duration): Unit = this.duration.plus(duration)
  136.  
  137.     override def accept(visitor: Visitor): Unit = visitor.visit(this)
  138. }
  139.  
  140. @ConcreteDecorator
  141. @Leaf
  142. @ConcreteElement
  143. case class DependentTask(aTask: Task, anotherTask: Task) extends Task {
  144.     override def description: String = aTask.description
  145.  
  146.     override def duration: Duration = aTask.duration
  147.  
  148.     override def dueDate: Option[Instant] = aTask.dueDate
  149.  
  150.     override def completionDate: Option[Instant] = aTask.completionDate
  151.  
  152.     override def startDate: Option[Instant] = aTask.startDate
  153.  
  154.     override def context: Option[String] = aTask.context
  155.  
  156.     override def priority: Option[Char] = aTask.priority
  157.  
  158.     override def markDone(): Unit = aTask.markDone()
  159.  
  160.     override def addTime(duration: Duration): Unit = aTask.addTime(duration)
  161.  
  162.     override def accept(visitor: Visitor): Unit = visitor.visit(this)
  163. }
  164.  
  165. @ConcreteDecorator
  166. @Leaf
  167. @ConcreteElement
  168. case class BillableTask(aTask: Task, rate: Double) extends Task {
  169.     override def description: String = aTask.description
  170.  
  171.     override def duration: Duration = aTask.duration
  172.  
  173.     override def dueDate: Option[Instant] = aTask.dueDate
  174.  
  175.     override def completionDate: Option[Instant] = aTask.completionDate
  176.  
  177.     override def startDate: Option[Instant] = aTask.startDate
  178.  
  179.     override def context: Option[String] = aTask.context
  180.  
  181.     override def priority: Option[Char] = aTask.priority
  182.  
  183.     override def markDone(): Unit = aTask.markDone()
  184.  
  185.     override def addTime(duration: Duration): Unit = aTask.addTime(duration)
  186.  
  187.     override def accept(visitor: Visitor): Unit = visitor.visit(this)
  188. }
  189.  
  190.  
  191. @ConcreteBuilder
  192. class TaskBuilder(private var description: String) {
  193.     private var dueDate: Option[Instant] = None
  194.     private var context: Option[String] = None
  195.     private var priority: Option[Char] = None
  196.     private var dependence: Option[Task] = None
  197.     private var rate: Option[Double] = None
  198.     private var startDate: Option[Instant] = None
  199.  
  200.     def addDueDate(instant: Instant): TaskBuilder = {
  201.         require(this.dueDate.isEmpty)
  202.         dueDate = Some(instant)
  203.         this
  204.     }
  205.  
  206.     def addContext(context: String): TaskBuilder = {
  207.         require(this.context.isEmpty)
  208.         this.context = Some(context)
  209.         this
  210.     }
  211.  
  212.     def addPriority(prio: Char): TaskBuilder = {
  213.         require(priority.isEmpty)
  214.         require(prio >= 'A' && prio <= 'Z')
  215.         this.priority = Some(prio)
  216.         this
  217.     }
  218.  
  219.     def addDependency(task: Task): TaskBuilder = {
  220.         require(dependence.isEmpty)
  221.         dependence = Some(task)
  222.         this
  223.     }
  224.  
  225.     def addRate(rate: Double): TaskBuilder = {
  226.         require(this.rate.isEmpty)
  227.         this.rate = Some(rate)
  228.         this
  229.     }
  230.  
  231.     def addStartDate(startDate:Instant): TaskBuilder = {
  232.         require(this.startDate.isEmpty)
  233.         this.startDate = Some(startDate)
  234.         this
  235.     }
  236.  
  237.     def build(): Task =  {
  238.         if(this.startDate.isEmpty)
  239.             this.startDate = Some(Instant.now)
  240.  
  241.         if(this.dependence.isDefined)
  242.             DependentTask(SimpleTask(description, dueDate, context, priority, startDate), this.dependence.get)
  243.         else if (this.rate.isDefined)
  244.             BillableTask(SimpleTask(description, dueDate, context, priority, startDate), this.rate.get)
  245.         else
  246.             SimpleTask(description, dueDate, context, priority, startDate)
  247.     }
  248. }
  249.  
  250. @Composite
  251. @ConcreteElement
  252. class Project private(val name: String) extends Visitable {
  253.     var list: Seq[Task] = Nil
  254.  
  255.     def initialize(tasks: Seq[Task]) = list = tasks
  256.  
  257.     @ChildManagement
  258.     def add(task: Task): Unit = list = list :+ task
  259.  
  260.     @ChildManagement
  261.     def remove(index: Int): Unit = list.patch(index, Nil, 1)
  262.  
  263.     override def accept(visitor: Visitor): Unit = visitor.visit(this)
  264. }
  265.  
  266. object Project {
  267.     def create(name: String, tasks: Task*): Project = {
  268.         val aProject: Project = new Project(name)
  269.         aProject.initialize(tasks)
  270.         aProject
  271.     }
  272. }
  273.  
  274. class TaskList(t: List[Visitable], val f: OutputFormat) extends Export[String] {
  275.     def result: String = ???
  276. }
  277.  
  278. case object TodoTXT
  279.  
  280. case object CSV
  281.  
  282. object Runner {
  283.  
  284.     def main(args: Array[String]): Unit = {
  285.         var list = new TaskBuilder("task1").build() :: Nil
  286.         list = new TaskBuilder("task2").addDependency(list.head).addDueDate(Instant.now().plus(6,
  287.             ChronoUnit.DAYS)).build() :: list
  288.         list = new TaskBuilder("task3").addContext("phone").addDueDate(Instant.now().plus(5,
  289.             ChronoUnit.DAYS)).build() :: list
  290.         list = new TaskBuilder("task4").addPriority('A').addRate(10.0).build() :: list
  291.         list = new TaskBuilder("task5").addContext("phone").addRate(10.0).addPriority('B')
  292.             .addDueDate(Instant.now().plus(5, ChronoUnit.DAYS)).addDependency(list(1)).build() :: list
  293.         list.head.addTime(Duration.of(8L, ChronoUnit.HOURS))
  294.         list.head.markDone()
  295.         list = list.reverse
  296.         val project = Project.create("all", list: _*)
  297.  
  298.         var visitableList:List[Visitable] = new TaskBuilder("task6").addContext("phone").addRate(10.0)
  299.             .addPriority('B')
  300.             .addDueDate(Instant.now().plus(5, ChronoUnit.DAYS))
  301.             .addDependency(list(4)).build() :: Nil
  302.         visitableList = project :: visitableList
  303.  
  304. //        println(new TaskList(visitableList, CSV).result)
  305. //        println(new TaskList(visitableList, TodoTXT).result)
  306.  
  307.         val invoiceVisitor = new InvoiceVisitor
  308.         val deadlineVisitor = new NextDeadlineVisitor
  309.         val validationVisitor = new ValidationVisitor
  310.  
  311.  
  312.         project.accept(invoiceVisitor)
  313.         project.accept(deadlineVisitor)
  314.         project.accept(validationVisitor)
  315.  
  316.         println(invoiceVisitor.getInvoice)
  317.         println(deadlineVisitor.getNextDeadline)
  318.         println(validationVisitor.isConsistent)
  319.     }
  320.  
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement