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

sp.domain.logic.IDAbleLogic.scala Maven / Gradle / Ivy

package sp.domain.logic

/**
 * Created by kristofer on 30/09/14.
 */
object IDAbleLogic {

  import sp.domain._
  import sp.domain.logic.SOPLogic._



  def removeID(id: Set[ID], ids: List[IDAble]) = {
    def removeFrom(item: IDAble): Option[IDAble] = {
      val newItem = item match {
        case x: Operation => removeIDFromOperation(id, x)
        case x: Thing => removeIDFromThing(id, x)
        case x: SPSpec => removeIDFromSPSpec(id, x)
        case x: SOPSpec => removeIDFromSOPSpec(id, x)
        case x:Struct => removeIDFromStruct(id, x)
        case _ => item
      }
      if (newItem == item) None
      else {
        Some(newItem)
      }
    }

    val t = ids flatMap removeFrom
    println(s"removeID: $t")
    t
  }




  def removeIDFromThing(id: Set[ID], th: Thing): Thing = {
    val newAttr = removeIDFromAttribute(id, th.attributes)
    if (newAttr == th.attributes)
      th
    else
      th.copy(attributes = newAttr)
  }

  def removeIDFromOperation(id: Set[ID], op: Operation): Operation = {
    val newAttr = removeIDFromAttribute(id, op.attributes)
    val removeIt = removeIDFromCondition(id, (_: Condition))
    val newCond = op.conditions map removeIt
    if (newAttr == op.attributes && newCond == op.conditions)
      op
    else
      op.copy(conditions = newCond, attributes = newAttr)
  }

  def removeIDFromSPSpec(id: Set[ID], obj: SPSpec): SPSpec = {
    val newAttr = removeIDFromAttribute(id, obj.attributes)
    if (newAttr == obj.attributes)
      obj
    else
      obj.copy(attributes = newAttr)
  }

  def removeIDFromSOPSpec(id: Set[ID], obj: SOPSpec): SOPSpec = {
    val newAttr = removeIDFromAttribute(id, obj.attributes)
    val newSOP = obj.sop flatMap(sop => removeIDFromSOP(id, sop))
    if (newAttr == obj.attributes && newSOP == obj.sop)
      obj
    else
      obj.copy(sop = newSOP, attributes = newAttr)
  }

  def removeIDFromStruct(id: Set[ID], obj: Struct): Struct = {
    val newAttr = removeIDFromAttribute(id, obj.attributes)
    val newCh = obj.items.flatMap((c => removeIDFromStructNode(id, c)))
    if (newAttr == obj.attributes && newCh == obj.items)
      obj
    else
      obj.copy(items = newCh, attributes = newAttr)
  }

  def removeIDFromStructNode(ids: Set[ID], obj: StructNode): Option[StructNode] = {
    val p = obj.parent.flatMap(x => if (ids.contains(x)) None else Some(x))
    val newAttr = removeIDFromAttribute(ids, obj.attributes)

    if (ids.contains(obj.item)) None else Some(obj.copy(parent = p, attributes = newAttr))
  }

  def removeIDFromSOP(id: Set[ID], sop: SOP): Option[SOP] = {
    def filter(xs: List[SOP]) = {
      println(s"id: $id, \n filter: $xs")
      val t = xs flatMap(x => removeIDFromSOP(id, x))
      println(s"res: $t")
      if (t == xs) xs else t
    }

    val t = sop match {
      case h: OperationNode => {
        if (id.contains(h.operation)) None
        else {
          val newChildren = filter(h.sop)
          if (newChildren == sop.sop) Some(h)
          else Some(h.copy(sop = newChildren))
        }
      }
      case EmptySOP => Some(EmptySOP)
      case _ => {
        val newChildren = filter(sop.sop)
        if (newChildren == sop.sop)
          Some(sop)
        else if (newChildren.isEmpty)
          None
        else if (newChildren.size == 1)
          Some(newChildren.head)
        else
          Some(sop.modifySOP(newChildren))
      }
    }

//    println(s"sop before: $sop")
//    println(s"sop after: $t")

    t
  }


  def removeIDFromCondition(id: Set[ID], cond: Condition): Condition = {
    cond match {
      case c @ Condition(guard, action, attr) => {
        val newGuard = removeIDFromProposition(id, guard)
        val newActions = removeIDFromAction(id, action)
        val newAttr = removeIDFromAttribute(id, attr)
        Condition(newGuard, newActions, newAttr)
      }
      case _ => cond
    }
  }

  def removeIDFromProposition(id: Set[ID], prop: Proposition): Proposition = {
    def clean(xs: List[Proposition], make: List[Proposition] => Proposition) = xs match {
      case Nil => None
      case _ => Some(make(xs))
    }
    def removeIDFromStateEvaluator(sv: StateEvaluator): Option[StateEvaluator] = {
      sv match {
        case SVIDEval(svid) => if (id.contains(svid)) None else Some(sv)
        case ValueHolder(v) => {
          removeIDFromAttrValue(id.map(_.toString), v) map ValueHolder
        }
        case _ => Some(sv)
      }
    }
    def req(prop: Proposition): Option[Proposition] = {
      prop match {
        case AND(xs) => clean(xs flatMap req, AND.apply)
        case OR(xs) => clean(xs flatMap req, OR.apply)
        case NOT(x) => clean(List(x) flatMap req, AND.apply) // AND will never be used
        case EQ(left, right) => {
          for {
            l <- removeIDFromStateEvaluator(left)
            r <- removeIDFromStateEvaluator(right)
          } yield EQ(l, r)
        }
        case NEQ(left, right) => {
          for {
            l <- removeIDFromStateEvaluator(left)
            r <- removeIDFromStateEvaluator(right)
          } yield NEQ(l, r)
        }
        case _ => Some(prop)
      }

    }

    req(prop) match {
      case Some(x) => x
      case None => AlwaysTrue
    }
  }


  def removeIDFromAction(id: Set[ID], actions: List[Action]): List[Action] = {
    actions flatMap {
      case a @ Action(svid, ValueHolder(v)) => {
        val newV = removeIDFromAttrValue(id.map(_.toString), v)
        if (id.contains(svid) || newV == None) None
        else Some(Action(svid, ValueHolder(newV.get)))
      }
      case a @ Action(svid, ASSIGN(assignID)) => {
        if (id.contains(svid) || id.contains(assignID)) None
        else Some(a)
      }
      case a @ Action(svid, _) => {
        if (id.contains(svid)) None
        else Some(a)
      }
    }
  }

  // TODO: Update this to play json transformers
  import play.api.libs.json._
  def removeIDFromAttribute(id: Set[ID], attr: SPAttributes): SPAttributes = {
    val idSet = id.map(_.toString())
    val updated = reqRemoveFromAttr(idSet, attr.value.toMap)
    if (updated == attr.value.toMap) attr else JsObject(updated)
  }
  def removeIDFromAttrValue(ids: Set[String], attrVal: SPValue): Option[SPValue] = {
    attrVal match {
      case x: JsString => if (ids.contains(x.value)) None else Some(attrVal)
      case x: JsObject => {
        val upd = reqRemoveFromAttr(ids, x.value.toMap)
        Some(JsObject(upd))
      }
      case JsArray(xs) => {
        val upd  = xs flatMap ((v => removeIDFromAttrValue(ids, v)))
        Some(JsArray(upd))
      }
      case _ => Some(attrVal)
    }
  }
  private def reqRemoveFromAttr(id: Set[String], keyVal: Map[String, JsValue]): Map[String, JsValue] = {
    keyVal.flatMap { case (key, attr) =>
      removeIDFromAttrValue(id, attr).map(x => key -> x)
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy