package org.kevoree.kevscript.statement; import org.jetbrains.annotations.NotNull; import org.kevoree.ComponentInstance; import org.kevoree.ContainerNode; import org.kevoree.ContainerRoot; import org.kevoree.Instance; import org.kevoree.kevscript.KevScriptError; import org.kevoree.kevscript.Type; import org.kevoree.kevscript.expression.InstancePathExpr; import org.kevoree.kevscript.expression.NameListExpr; import org.waxeye.ast.IAST; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * * Created by leiko on 12/15/16. */ public class MoveStmt { public static void interpret(IAST<Type> stmt, ContainerRoot model, Map<String, String> ctxVars) throws Exception { List<List<String>> instancesToMove = NameListExpr.interpret(stmt.getChildren().get(0), ctxVars); List<String> targetNodes = InstancePathExpr.interpret(stmt.getChildren().get(1), ctxVars); List<ContainerNode> targets; if (targetNodes.size() == 1) { targets = getContainerNodes(model, targetNodes); } else { throw new KevScriptError("Move target path is invalid (" + targetNodes.toString() + ")"); } for (List<String> instancePath : instancesToMove) { if (instancePath.size() == 1) { if (instancePath.get(0).equals("*")) { throw new KevScriptError("Wilcard \"*\" cannot be used for nodes. Move failed"); } else { // specific node instance ContainerNode node = model.findNodesByID(instancePath.get(0)); if (node != null) { for (ContainerNode targetNode : targets) { apply(node, targetNode); } } else { throw new KevScriptError("Unable to move node instance \""+ instancePath.get(0)+"\". Instance does not exist"); } } } else if (instancePath.size() == 2) { List<ContainerNode> hostNodes = getContainerNodes(model, instancePath); List<ComponentInstance> components = new ArrayList<>(); if (instancePath.get(1).equals("*")) { // all components for (ContainerNode host : hostNodes) { components.addAll(host.getComponents()); } } else { // specific component for (ContainerNode host : hostNodes) { ComponentInstance comp = host.findComponentsByID(instancePath.get(1)); if (comp != null) { components.add(comp); } } } for (ContainerNode targetNode : targets) { for (ComponentInstance comp : components) { apply(comp, targetNode); } } } else { throw new KevScriptError("\""+instancePath.toString()+"\" is not a valid move path for an instance"); } } } @NotNull private static List<ContainerNode> getContainerNodes(ContainerRoot model, List<String> targetNodes) { List<ContainerNode> nodes = new ArrayList<>(); if (targetNodes.get(0).equals("*")) { // select all nodes in the model nodes.addAll(model.getNodes()); } else { // specific node ContainerNode node = model.findNodesByID(targetNodes.get(0)); if (node != null) { nodes.add(node); } else { throw new KevScriptError("Unable to find node instance \"" + targetNodes.get(0) + "\". Move failed"); } } return nodes; } private static void apply(Instance leftH, ContainerNode targetNode) { if (leftH instanceof ComponentInstance) { targetNode.addComponents((ComponentInstance) leftH); } else { if (leftH instanceof ContainerNode) { targetNode.addHosts((ContainerNode) leftH); } else { throw new KevScriptError("\""+leftH.getName()+"\" is not a node instance nor a component. Move failed"); } } } }