Commit 1ba254f3 authored by Romain Reuillon's avatar Romain Reuillon
Browse files

[Core] enh: re-design transition DSL from scratch.

parent ef4bbeec
......@@ -29,7 +29,6 @@ import org.openmole.core.project._
import org.openmole.core.tools.io.Prettifier._
import org.openmole.core.workflow.execution.Environment
import org.openmole.core.workflow.mole.{ Mole, MoleExecution }
import org.openmole.core.workflow.puzzle._
import org.openmole.core.workflow.validation.Validation
import org.openmole.core.module
import org.openmole.core.pluginmanager.PluginManager
......@@ -125,10 +124,10 @@ class Command(val console: ScalaREPL, val variables: ConsoleVariables) { command
}
finally ConsoleVariables.bindVariables(console, variables)
def load(file: File, args: Seq[String] = Seq.empty)(implicit services: Services): Puzzle =
def load(file: File, args: Seq[String] = Seq.empty)(implicit services: Services): DSL =
loadAny(file) match {
case res: Puzzle res
case x throw new UserBadDataError("The result is not a puzzle")
case res: DSL res
case x throw new UserBadDataError("The result is not a puzzle")
}
def modules(urls: OptionalArgument[Seq[String]] = None)(implicit preference: Preference, randomProvider: RandomProvider, newFile: NewFile, fileService: FileService): Unit = {
......
......@@ -24,11 +24,11 @@ import org.openmole.core.preference.Preference
import org.openmole.core.project._
import org.openmole.core.tools.io.Prettifier._
import org.openmole.tool.crypto.Cypher
import org.openmole.tool.file._
import org.openmole.tool.logger.JavaLogger
import org.openmole.core.services._
import org.openmole.core.workflow.mole._
import org.openmole.core.workspace.NewFile
import org.openmole.core.dsl._
import scala.annotation.tailrec
import scala.util._
......@@ -127,7 +127,7 @@ class Console(script: Option[String] = None) {
Try(compiled.eval) match {
case Success(res)
MoleServices.create
val ex = res.toExecution()
val ex = dslToPuzzle(res).toExecution()
Try(ex.run) match {
case Failure(e)
println(e.stackString)
......
......@@ -9,8 +9,8 @@ object Generate {
def run(args: Array[String]): Int = {
case class Parameters(
target: Option[File] = None,
ignored: List[String] = Nil
target: Option[File] = None,
ignored: List[String] = Nil
)
@tailrec def parse(args: List[String], c: Parameters = Parameters()): Parameters = args match {
......
......@@ -372,8 +372,7 @@ lazy val distributionDomain = OsgiProject(pluginDir, "org.openmole.plugin.domain
lazy val fileDomain = OsgiProject(pluginDir, "org.openmole.plugin.domain.file", imports = Seq("*")) dependsOn (openmoleDSL) settings (pluginSettings: _*)
lazy val modifierDomain = OsgiProject(pluginDir, "org.openmole.plugin.domain.modifier", imports = Seq("*")) dependsOn (openmoleDSL) settings (
libraryDependencies += Libraries.scalatest
) settings (pluginSettings: _*)
libraryDependencies += Libraries.scalatest) settings (pluginSettings: _*)
lazy val rangeDomain = OsgiProject(pluginDir, "org.openmole.plugin.domain.range", imports = Seq("*")) dependsOn (openmoleDSL) settings (pluginSettings: _*)
......
......@@ -32,12 +32,4 @@ trait Classes {
lazy val ExplorationTask = task.ExplorationTask
lazy val MoleTask = task.MoleTask
lazy val Capsule = mole.Capsule
lazy val StrainerCapsule = mole.StrainerCapsule
lazy val MasterCapsule = mole.MasterCapsule
lazy val Slot = transition.Slot
lazy val Puzzle = puzzle.Puzzle
}
package org.openmole.core.dsl
import org.openmole.core.context.Context
import org.openmole.core.expansion.ExpandedString
import org.scalatest._
class DSLSpec extends FlatSpec with Matchers {
import Stubs._
"Seq of default" should "be convertible to Context" in {
val a = Val[Int]
val b = Val[String]
val c: Context = Seq(a := 7, b := "great")
}
}
......@@ -21,6 +21,8 @@ package expansion {
trait ExpansionPackage {
implicit def seqToSeqOfFromContext[T](s: Seq[T])(implicit toFromContext: ToFromContext[T, T]): Seq[FromContext[T]] = s.map(e toFromContext(e))
type Condition = expansion.Condition
lazy val Condition = expansion.Condition
}
}
......
......@@ -21,7 +21,6 @@ import javax.script.CompiledScript
import org.openmole.core.console._
import org.openmole.core.pluginmanager._
import org.openmole.core.project.Imports.{ SourceFile, Tree }
import org.openmole.core.workflow.puzzle._
import org.openmole.tool.file._
import monocle.function.all._
import monocle.std.all._
......@@ -29,6 +28,7 @@ import org.openmole.core.exception.{ InternalProcessingError, UserBadDataError }
import org.openmole.core.fileservice.FileService
import org.openmole.core.outputmanager.OutputManager
import org.openmole.core.services._
import org.openmole.core.workflow.composition.DSL
import org.openmole.core.workspace.NewFile
import org.openmole.tool.hash._
......@@ -103,7 +103,7 @@ object Project {
new Project(workDirectory, v Project.newREPL(v))
trait OMSScript {
def run(): Puzzle
def run(): DSL
}
}
......@@ -120,8 +120,8 @@ case class Compiled(result: ScalaREPL.Compiled) extends CompileResult {
def eval =
result.apply().asInstanceOf[Project.OMSScript].run() match {
case p: Puzzle p
case e throw new UserBadDataError(s"Script should end with a workflow (it ends with ${if (e == null) null else e.getClass}).")
case p: DSL p
case e throw new UserBadDataError(s"Script should end with a workflow (it ends with ${if (e == null) null else e.getClass}).")
}
}
......@@ -141,7 +141,7 @@ class Project(workDirectory: File, newREPL: (ConsoleVariables) ⇒ ScalaREPL) {
|
|new ${classOf[Project.OMSScript].getCanonicalName} {
|
|def run(): ${classOf[Puzzle].getCanonicalName} = {
|def run(): ${classOf[DSL].getCanonicalName} = {
|import ${Project.uniqueName(script)}._imports._""".stripMargin
def footer =
......
......@@ -27,6 +27,4 @@ trait Id {
else if (!classOf[Id].isAssignableFrom(other.asInstanceOf[AnyRef].getClass)) false
else id.equals(other.asInstanceOf[Id].id)
}
override def toString = id.toString
}
......@@ -16,17 +16,16 @@ class Activator extends BundleActivator {
import org.openmole.core.pluginmanager.KeyWord._
import org.openmole.core.context._
import org.openmole.core.workflow.mole._
import org.openmole.core.workflow.transition.{ Slot }
import org.openmole.core.workflow.transition.{ TransitionSlot }
import org.openmole.core.workflow.execution.{ LocalEnvironment }
import org.openmole.core.workflow.puzzle.Puzzle
import org.openmole.core.workflow.task.{ EmptyTask, ExplorationTask, ClosureTask, ToArrayTask, MoleTask, FromContextTask }
Vector(
Word(classOf[Val[_]]),
Word(classOf[Capsule]),
Word(classOf[MasterCapsule]),
Word(classOf[Slot]),
Word(classOf[Puzzle]),
Word("Capsule"),
Word("Slot"),
Word("Capsule"),
Word("Strain"),
Word("in"),
Word("is"),
Word("on"),
......@@ -46,7 +45,6 @@ class Activator extends BundleActivator {
Transition(">-"),
Transition("-<-"),
Transition(">|"),
Transition("--="),
Transition("oo"),
Environment(classOf[LocalEnvironment]),
Task(objectName(EmptyTask)),
......
/*
* Copyright (C) 2012 Romain Reuillon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.openmole.core.workflow.mole
import org.openmole.core.context.{ Context, Val }
import org.openmole.core.workflow.task._
object MasterCapsule {
def apply(task: Task, persist: Seq[Val[_]], strain: Boolean) = new MasterCapsule(task, persist.map(_.name), strain)
def apply(t: Task, persist: Val[_]*): MasterCapsule = apply(t, persist, false)
}
class MasterCapsule(task: Task, val persist: Seq[String] = Seq.empty, strainer: Boolean) extends Capsule(task, strainer) {
def toPersist(context: Context): Context =
persist.map { n context.variable(n).get }
}
\ No newline at end of file
......@@ -25,10 +25,10 @@ import scala.collection._
object Mole {
def nextCapsules(mole: Mole)(from: Capsule, lvl: Int) =
def nextCapsules(mole: Mole)(from: MoleCapsule, lvl: Int) =
nextTransitions(mole)(from, lvl).map { case (t, lvl) t.end.capsule lvl }
def nextTransitions(mole: Mole)(from: Capsule, lvl: Int) =
def nextTransitions(mole: Mole)(from: MoleCapsule, lvl: Int) =
mole.outputTransitions(from).map {
case t: IAggregationTransition t (lvl - 1)
case t: IEndExplorationTransition t (lvl - 1)
......@@ -57,13 +57,13 @@ object Mole {
}
case class Mole(
root: Capsule,
root: MoleCapsule,
transitions: Iterable[ITransition] = Iterable.empty,
dataChannels: Iterable[DataChannel] = Iterable.empty,
inputs: PrototypeSet = PrototypeSet.empty
) {
lazy val slots = (Slot(root) :: transitions.map(_.end).toList).groupBy(_.capsule).mapValues(_.toSet).withDefault(c Iterable.empty)
lazy val slots = (TransitionSlot(root) :: transitions.map(_.end).toList).groupBy(_.capsule).mapValues(_.toSet).withDefault(c Iterable.empty)
lazy val capsules = slots.keys
lazy val inputTransitions = transitions.groupBy(_.end).mapValues(_.toSet).withDefault(c Iterable.empty)
lazy val outputTransitions = transitions.groupBy(_.start).mapValues(_.toSet).withDefault(c Iterable.empty)
......@@ -71,5 +71,5 @@ case class Mole(
lazy val outputDataChannels = dataChannels.groupBy(_.start).mapValues(_.toSet).withDefault(c Iterable.empty)
lazy val levels = Mole.levels(this)
def level(c: Capsule) = levels(c)
def level(c: MoleCapsule) = levels(c)
}
......@@ -26,16 +26,16 @@ import org.openmole.core.workflow.transition._
import org.openmole.core.workflow.validation._
import org.openmole.tool.random._
object Capsule {
object MoleCapsule {
implicit def taskToCapsuleConverter(task: Task) = Capsule(task)
implicit def slotToCapsuleConverter(slot: Slot) = slot.capsule
implicit def taskToCapsuleConverter(task: Task) = MoleCapsule(task)
implicit def slotToCapsuleConverter(slot: TransitionSlot) = slot.capsule
def apply(task: Task, strain: Boolean = false) = new Capsule(task, strain)
def apply(task: Task, strain: Boolean = false) = new MoleCapsule(task, strain)
def isStrainer(c: Capsule) = c.strainer
def isStrainer(c: MoleCapsule) = c.strainer
def reachNoStrainer(mole: Mole)(slot: Slot, seen: Set[Slot] = Set.empty): Boolean = {
def reachNoStrainer(mole: Mole)(slot: TransitionSlot, seen: Set[TransitionSlot] = Set.empty): Boolean = {
if (slot.capsule == mole.root) true
else if (seen.contains(slot)) false
else {
......@@ -58,7 +58,7 @@ object Capsule {
* @param _task task inside this capsule
* @param strainer true if this capsule let pass all data through
*/
class Capsule(_task: Task, val strainer: Boolean) {
class MoleCapsule(_task: Task, val strainer: Boolean) {
lazy val task =
strainer match {
......@@ -110,7 +110,7 @@ class Capsule(_task: Task, val strainer: Boolean) {
if (this == mole.root) mole.inputs
else {
val slots = mole.slots(this)
val noStrainer = slots.toSeq.filter(s Capsule.reachNoStrainer(mole)(s))
val noStrainer = slots.toSeq.filter(s MoleCapsule.reachNoStrainer(mole)(s))
val bySlot =
for {
......@@ -147,5 +147,16 @@ class StrainerTaskDecorator(val task: Task) extends Task {
}
object StrainerCapsule {
def apply(task: Task) = Capsule(task, strain = true)
def apply(task: Task) = MoleCapsule(task, strain = true)
}
object MasterCapsule {
def apply(task: Task, persist: Seq[Val[_]], strain: Boolean) = new MasterCapsule(task, persist.map(_.name), strain)
def apply(t: Task, persist: Val[_]*): MasterCapsule = apply(t, persist, false)
}
class MasterCapsule(task: Task, val persist: Seq[String] = Seq.empty, strainer: Boolean) extends MoleCapsule(task, strainer) {
def toPersist(context: Context): Context =
persist.map { n context.variable(n).get }
}
\ No newline at end of file
......@@ -52,10 +52,10 @@ object MoleExecution extends JavaLogger {
class Starting extends Event[MoleExecution]
case class Finished(canceled: Boolean) extends Event[MoleExecution]
case class JobStatusChanged(moleJob: MoleJob, capsule: Capsule, newState: State, oldState: State) extends Event[MoleExecution]
case class JobCreated(moleJob: MoleJob, capsule: Capsule) extends Event[MoleExecution]
case class JobSubmitted(moleJob: Job, capsule: Capsule, environment: Environment) extends Event[MoleExecution]
case class JobFinished(moleJob: MoleJob, capsule: Capsule) extends Event[MoleExecution]
case class JobStatusChanged(moleJob: MoleJob, capsule: MoleCapsule, newState: State, oldState: State) extends Event[MoleExecution]
case class JobCreated(moleJob: MoleJob, capsule: MoleCapsule) extends Event[MoleExecution]
case class JobSubmitted(moleJob: Job, capsule: MoleCapsule, environment: Environment) extends Event[MoleExecution]
case class JobFinished(moleJob: MoleJob, capsule: MoleCapsule) extends Event[MoleExecution]
object MoleExecutionFailed {
def exception(moleExecutionError: MoleExecutionFailed) = moleExecutionError.exception
......@@ -72,23 +72,23 @@ object MoleExecution extends JavaLogger {
def exception: Throwable
}
case class JobFailed(moleJob: MoleJob, capsule: Capsule, exception: Throwable) extends Event[MoleExecution] with MoleExecutionFailed {
case class JobFailed(moleJob: MoleJob, capsule: MoleCapsule, exception: Throwable) extends Event[MoleExecution] with MoleExecutionFailed {
def level = Level.SEVERE
}
case class ExceptionRaised(moleJob: MoleJob, capsule: Capsule, exception: Throwable, level: Level) extends Event[MoleExecution] with MoleExecutionFailed
case class SourceExceptionRaised(source: Source, capsule: Capsule, exception: Throwable, level: Level) extends Event[MoleExecution] with MoleExecutionFailed
case class HookExceptionRaised(hook: Hook, capsule: Capsule, moleJob: MoleJob, exception: Throwable, level: Level) extends Event[MoleExecution] with MoleExecutionFailed
case class ExceptionRaised(moleJob: MoleJob, capsule: MoleCapsule, exception: Throwable, level: Level) extends Event[MoleExecution] with MoleExecutionFailed
case class SourceExceptionRaised(source: Source, capsule: MoleCapsule, exception: Throwable, level: Level) extends Event[MoleExecution] with MoleExecutionFailed
case class HookExceptionRaised(hook: Hook, capsule: MoleCapsule, moleJob: MoleJob, exception: Throwable, level: Level) extends Event[MoleExecution] with MoleExecutionFailed
case class MoleExecutionError(exception: Throwable) extends MoleExecutionFailed
private def listOfTupleToMap[K, V](l: Traversable[(K, V)]): Map[K, Traversable[V]] = l.groupBy(_._1).mapValues(_.map(_._2))
def apply(
mole: Mole,
sources: Iterable[(Capsule, Source)] = Iterable.empty,
hooks: Iterable[(Capsule, Hook)] = Iterable.empty,
environments: Map[Capsule, EnvironmentProvider] = Map.empty,
grouping: Map[Capsule, Grouping] = Map.empty,
sources: Iterable[(MoleCapsule, Source)] = Iterable.empty,
hooks: Iterable[(MoleCapsule, Hook)] = Iterable.empty,
environments: Map[MoleCapsule, EnvironmentProvider] = Map.empty,
grouping: Map[MoleCapsule, Grouping] = Map.empty,
implicits: Context = Context.empty,
defaultEnvironment: OptionalArgument[LocalEnvironmentProvider] = None,
cleanOnFinish: Boolean = true,
......@@ -119,7 +119,7 @@ object MoleExecution extends JavaLogger {
)
}
type CapsuleStatuses = Map[Capsule, JobStatuses]
type CapsuleStatuses = Map[MoleCapsule, JobStatuses]
case class JobStatuses(ready: Long, running: Long, completed: Long)
......@@ -146,7 +146,7 @@ object MoleExecution extends JavaLogger {
subMoleExecutionState.parent.foreach(s updateNbJobs(s, v))
}
def submit(subMoleExecutionState: SubMoleExecutionState, capsule: Capsule, context: Context, ticket: Ticket): Unit = {
def submit(subMoleExecutionState: SubMoleExecutionState, capsule: MoleCapsule, context: Context, ticket: Ticket): Unit = {
import subMoleExecutionState.moleExecution.executionContext.services._
if (!subMoleExecutionState.canceled) {
updateNbJobs(subMoleExecutionState, 1)
......@@ -212,7 +212,7 @@ object MoleExecution extends JavaLogger {
}
}
def jobFinished(subMoleExecutionState: SubMoleExecutionState, job: MoleJob, capsule: Capsule, ticket: Ticket) = {
def jobFinished(subMoleExecutionState: SubMoleExecutionState, job: MoleJob, capsule: MoleCapsule, ticket: Ticket) = {
val mole = subMoleExecutionState.moleExecution.mole
def ctxForHooks = (subMoleExecutionState.moleExecution.implicits + job.context) - Variable.openMOLESeed
......@@ -270,7 +270,7 @@ object MoleExecution extends JavaLogger {
def newChildSubMoleExecution(subMoleExecution: SubMoleExecutionState): SubMoleExecutionState =
newSubMoleExecution(Some(subMoleExecution), subMoleExecution.moleExecution)
def finalState(subMoleExecutionState: SubMoleExecutionState, job: MoleJob, state: State, capsule: Capsule, ticket: Ticket) = {
def finalState(subMoleExecutionState: SubMoleExecutionState, job: MoleJob, state: State, capsule: MoleCapsule, ticket: Ticket) = {
job.exception match {
case Some(e)
val error = MoleExecution.JobFailed(job, capsule, e)
......@@ -353,7 +353,7 @@ object MoleExecution extends JavaLogger {
def nextJobId(moleExecution: MoleExecution) = UUID.randomUUID
def group(moleExecution: MoleExecution, moleJob: MoleJob, capsule: Capsule) = {
def group(moleExecution: MoleExecution, moleJob: MoleJob, capsule: MoleCapsule) = {
moleExecution.grouping.get(capsule) match {
case Some(strategy)
val groups = moleExecution.waitingJobs.getOrElseUpdate(capsule, collection.mutable.Map())
......@@ -374,7 +374,7 @@ object MoleExecution extends JavaLogger {
}
}.map { case (j, c) submit(moleExecution, j, c) }
def submit(moleExecution: MoleExecution, job: Job, capsule: Capsule) =
def submit(moleExecution: MoleExecution, job: Job, capsule: MoleCapsule) =
if (!job.finished) {
val env = moleExecution.environments.getOrElse(capsule, moleExecution.defaultEnvironment)
import moleExecution.executionContext.services._
......@@ -435,7 +435,7 @@ object MoleExecution extends JavaLogger {
def allJobs(moleExecution: MoleExecution) = moleExecution.subMoleExecutions.values.flatMap(_.jobs.toVector.map { case (mj, c) c -> mj })
def capsuleStatuses(moleExecution: MoleExecution, jobs: Seq[(Capsule, MoleJob)], completed: Map[Capsule, Long]): CapsuleStatuses = {
def capsuleStatuses(moleExecution: MoleExecution, jobs: Seq[(MoleCapsule, MoleJob)], completed: Map[MoleCapsule, Long]): CapsuleStatuses = {
val runningSet: java.util.HashSet[UUID] = {
def submissionEnvironments = moleExecution.environments.values.toSeq.collect { case e: SubmissionEnvironment e }
......@@ -454,10 +454,10 @@ object MoleExecution extends JavaLogger {
def isRunningOnEnvironment(moleJob: MoleJob): Boolean = runningSet.contains(moleJob.id)
val ready = collection.mutable.Map[Capsule, Long]()
val running = collection.mutable.Map[Capsule, Long]()
val ready = collection.mutable.Map[MoleCapsule, Long]()
val running = collection.mutable.Map[MoleCapsule, Long]()
def increment(map: collection.mutable.Map[Capsule, Long], key: Capsule) = {
def increment(map: collection.mutable.Map[MoleCapsule, Long], key: MoleCapsule) = {
val value = map.getOrElse(key, 0L)
map.update(key, value + 1)
}
......@@ -493,7 +493,7 @@ object MoleExecution extends JavaLogger {
var nbJobs = 0
var children = collection.mutable.TreeMap[SubMoleExecution, SubMoleExecutionState]()
var jobs = collection.mutable.TreeMap[MoleJob, Capsule]()
var jobs = collection.mutable.TreeMap[MoleJob, MoleCapsule]()
var canceled = false
val onFinish = collection.mutable.ListBuffer[(SubMoleExecutionState Any)]()
val masterCapsuleRegistry = new MasterCapsuleRegistry
......@@ -528,11 +528,11 @@ sealed trait MoleExecutionMessage
object MoleExecutionMessage {
case class PerformTransition(subMoleExecution: SubMoleExecution)(val operation: SubMoleExecutionState Unit) extends MoleExecutionMessage
case class JobFinished(subMoleExecution: SubMoleExecution)(val job: MoleJob, val state: State, val capsule: Capsule, val ticket: Ticket) extends MoleExecutionMessage
case class JobFinished(subMoleExecution: SubMoleExecution)(val job: MoleJob, val state: State, val capsule: MoleCapsule, val ticket: Ticket) extends MoleExecutionMessage
case class WithMoleExecutionSate(operation: MoleExecution Unit) extends MoleExecutionMessage
case class StartMoleExecution(context: Option[Context]) extends MoleExecutionMessage
case class CancelMoleExecution() extends MoleExecutionMessage
case class RegisterJob(subMoleExecution: SubMoleExecutionState, job: MoleJob, capsule: Capsule) extends MoleExecutionMessage
case class RegisterJob(subMoleExecution: SubMoleExecutionState, job: MoleJob, capsule: MoleCapsule) extends MoleExecutionMessage
case class CleanMoleExcution() extends MoleExecutionMessage
def msgForSubMole(msg: MoleExecutionMessage, subMoleExecutionState: SubMoleExecutionState) = msg match {
......@@ -595,8 +595,8 @@ class MoleExecution(
val mole: Mole,
val sources: Sources,
val hooks: Hooks,
val environmentProviders: Map[Capsule, EnvironmentProvider],
val grouping: Map[Capsule, Grouping],
val environmentProviders: Map[MoleCapsule, EnvironmentProvider],
val grouping: Map[MoleCapsule, Grouping],
val defaultEnvironmentProvider: LocalEnvironmentProvider,
val cleanOnFinish: Boolean,
val implicits: Context,
......@@ -633,11 +633,11 @@ class MoleExecution(
private[mole] val newGroup = NewGroup()
private[mole] val waitingJobs = collection.mutable.Map[Capsule, collection.mutable.Map[MoleJobGroup, ListBuffer[MoleJob]]]()
private[mole] val waitingJobs = collection.mutable.Map[MoleCapsule, collection.mutable.Map[MoleJobGroup, ListBuffer[MoleJob]]]()
private[mole] var nbWaiting = 0
private[mole] val completed = {
val map = collection.mutable.Map[Capsule, Long]()
val map = collection.mutable.Map[MoleCapsule, Long]()
map ++= mole.capsules.map(_ -> 0L)
map
}
......
......@@ -26,30 +26,30 @@ package mole {
package object mole {
case class Hooks(map: Map[Capsule, Traversable[Hook]])
case class Hooks(map: Map[MoleCapsule, Traversable[Hook]])
case class Sources(map: Map[Capsule, Traversable[Source]])
case class Sources(map: Map[MoleCapsule, Traversable[Source]])
implicit def hooksToMap(h: Hooks): Map[Capsule, Traversable[Hook]] = h.map.withDefault(_ List.empty)
implicit def hooksToMap(h: Hooks): Map[MoleCapsule, Traversable[Hook]] = h.map.withDefault(_ List.empty)
implicit def mapToHooks(m: Map[Capsule, Traversable[Hook]]): Hooks = new Hooks(m)
implicit def mapToHooks(m: Map[MoleCapsule, Traversable[Hook]]): Hooks = new Hooks(m)
implicit def iterableTupleToHooks(h: Iterable[(Capsule, Hook)]): Hooks =
implicit def iterableTupleToHooks(h: Iterable[(MoleCapsule, Hook)]): Hooks =
new Hooks(h.groupBy(_._1).mapValues(_.map(_._2)))
implicit def sourcesToMap(s: Sources): Map[Capsule, Traversable[Source]] = s.map.withDefault(_ List.empty)
implicit def sourcesToMap(s: Sources): Map[MoleCapsule, Traversable[Source]] = s.map.withDefault(_ List.empty)
implicit def mapToSources(m: Map[Capsule, Traversable[Source]]): Sources = new Sources(m)
implicit def mapToSources(m: Map[MoleCapsule, Traversable[Source]]): Sources = new Sources(m)
implicit def iterableTupleToSources(s: Iterable[(Capsule, Source)]): Sources =
implicit def iterableTupleToSources(s: Iterable[(MoleCapsule, Source)]): Sources =
new Sources(s.groupBy(_._1).mapValues(_.map(_._2)))
object Hooks {
def empty = Map.empty[Capsule, Traversable[Hook]]
def empty = Map.empty[MoleCapsule, Traversable[Hook]]
}
object Sources {
def empty = Map.empty[Capsule, Traversable[Source]]
def empty = Map.empty[MoleCapsule, Traversable[Source]]
}
}
\ No newline at end of file
......@@ -25,19 +25,17 @@ package workflow {
import org.openmole.core.keyword.KeyWordPackage
import org.openmole.core.workflow.builder.BuilderPackage