package org.kevoree.kevscript;
import org.kevoree.*;
import org.kevoree.impl.DefaultKevoreeFactory;
import org.kevoree.kevscript.util.InstanceResolver;
import org.kevoree.kevscript.util.MergeResolver;
import org.kevoree.kevscript.util.TypeDefinitionResolver;
import org.kevoree.loader.JSONModelLoader;
import org.kevoree.log.Log;
import org.kevoree.serializer.JSONModelSerializer;
import org.waxeye.ast.IAST;
import org.waxeye.input.BufferFiller;
import org.waxeye.input.InputBuffer;
import org.waxeye.parser.ParseResult;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: duke
* Date: 25/11/2013
* Time: 15:53
*/
public class KevScriptEngine {
Parser parser = new Parser();
KevoreeFactory factory = new DefaultKevoreeFactory();
public static void main(String[] args) throws FileNotFoundException {
KevScriptEngine engine = new KevScriptEngine();
JSONModelLoader loader = new JSONModelLoader();
ContainerRoot root = (ContainerRoot) loader.loadModelFromStream(new FileInputStream("/Users/duke/Documents/dev/dukeboard/kevoree/kevoree-tools/org.kevoree.tools.kevscript/src/examples/lib.json")).get(0);
engine.executeFromStream(new FileInputStream("/Users/duke/Documents/dev/dukeboard/kevoree/kevoree-tools/org.kevoree.tools.kevscript/src/examples/test.kevs"), root);
JSONModelSerializer saver = new JSONModelSerializer();
//saver.serializeToStream(root, System.out);
}
public void execute(String script, ContainerRoot model) {
ParseResult<Type> parserResult = parser.parse(new InputBuffer(script.toCharArray()));
interpret(parserResult.getAST(), model);
}
public void executeFromStream(InputStream script, ContainerRoot model) {
ParseResult<Type> parserResult = parser.parse(new InputBuffer(BufferFiller.asArray(script)));
interpret(parserResult.getAST(), model);
}
private List<Instance> pending = new ArrayList<Instance>();
public void interpret(IAST<Type> node, ContainerRoot model) {
switch (node.getType()) {
case KevScript:
for (IAST<Type> child : node.getChildren()) {
interpret(child, model);
}
break;
case Statement:
for (IAST<Type> child : node.getChildren()) {
interpret(child, model);
}
break;
case Add:
TypeDefinition td = TypeDefinitionResolver.resolve(model, node.getChildren().get(1).childrenAsString());
if (td == null) {
Log.error("TypeDefinition not found : {}", node.getChildren().get(1).childrenAsString());
} else {
IAST<Type> instanceNames = node.getChildren().get(0);
if (instanceNames.getType().equals(Type.NameList)) {
for (IAST<Type> name : instanceNames.getChildren()) {
applyAdd(td, name, model);
}
} else {
applyAdd(td, instanceNames, model);
}
}
break;
case Move:
List<Instance> leftHands = InstanceResolver.resolve(model, node.getChildren().get(0), pending);
List<Instance> rightHands = InstanceResolver.resolve(model, node.getChildren().get(1), pending);
for (Instance leftH : leftHands) {
for (Instance rightH : rightHands) {
pending.remove(leftH);
applyMove(leftH, rightH, model);
}
}
break;
case Attach:
List<Instance> leftHands2 = InstanceResolver.resolve(model, node.getChildren().get(0), pending);
List<Instance> rightHands2 = InstanceResolver.resolve(model, node.getChildren().get(1), pending);
for (Instance leftH : leftHands2) {
for (Instance rightH : rightHands2) {
applyAttach(leftH, rightH, model, false);
}
}
break;
case Detach:
List<Instance> leftHands3 = InstanceResolver.resolve(model, node.getChildren().get(0), pending);
List<Instance> rightHands3 = InstanceResolver.resolve(model, node.getChildren().get(1), pending);
for (Instance leftH : leftHands3) {
for (Instance rightH : rightHands3) {
applyAttach(leftH, rightH, model, true);
}
}
break;
case AddRepo:
Repository repo = factory.createRepository();
repo.setUrl(node.getChildren().get(0).childrenAsString());
model.addRepositories(repo);
break;
case Remove:
List<Instance> toRemove = InstanceResolver.resolve(model, node.getChildren().get(0), pending);
for (Instance toDrop : toRemove) {
toDrop.delete();
}
break;
case Network:
Log.error("Network not implemented yet !!!");
break;
case Merge:
MergeResolver.merge(model, node.getChildren().get(0).childrenAsString(), node.getChildren().get(1).childrenAsString());
break;
case Set:
List<Instance> toChangeDico = InstanceResolver.resolve(model, node.getChildren().get(0), pending);
for (Instance target : toChangeDico) {
if (target.getDictionary() == null) {
target.setDictionary(factory.createDictionary());
}
IAST<Type> dictionary = node.getChildren().get(1);
String targetNode = null;
for (IAST<Type> list : dictionary.getChildren()) {
if (list.getChildren().size() > 1) {
IAST<Type> last = list.getChildren().get(list.getChildren().size() - 1);
if (last.getType().equals(Type.String)) {
targetNode = last.childrenAsString();
}
}
for (IAST<Type> attribute : list.getChildren()) {
String key = attribute.getChildren().get(0).childrenAsString();
DictionaryValue att = target.getDictionary().findValuesByID(key);
if (att == null) {
att = factory.createDictionaryValue();
target.getDictionary().addValues(att);
}
String value = attribute.getChildren().get(1).childrenAsString();
att.setValue(value);
if (targetNode != null) {
att.setTargetNode(model.findNodesByID(targetNode));
if (att.getTargetNode() == null) {
Log.error("Node not found for @" + targetNode + " property");
}
}
}
}
}
break;
default:
// System.out.println(node);
break;
}
}
private void applyAttach(Instance leftH, Instance rightH, ContainerRoot model, boolean reverse) {
if (!(leftH instanceof ContainerNode)) {
Log.error("Not a ContainerNode {}", leftH.getName());
}
if (!(rightH instanceof Group)) {
Log.error("Not a Group {}", rightH.getName());
}
ContainerNode node = (ContainerNode) leftH;
Group group = (Group) rightH;
if (!reverse) {
group.addSubNodes(node);
} else {
group.removeSubNodes(node);
}
}
private void applyMove(Instance leftH, Instance rightH, ContainerRoot model) {
if (!(rightH instanceof ContainerNode)) {
Log.error("Not a ContainerNode {}", rightH.getName());
} else {
ContainerNode node = (ContainerNode) rightH;
if (leftH instanceof ComponentInstance) {
node.addComponents((ComponentInstance) leftH);
} else {
if (leftH instanceof ContainerNode) {
node.addHosts((ContainerNode) leftH);
} else {
Log.error("Not a containerNode or component : {}", leftH.getName());
}
}
}
}
private boolean applyAdd(TypeDefinition td, IAST<Type> name, ContainerRoot model) {
boolean process = false;
if (td instanceof NodeType) {
ContainerNode instance = factory.createContainerNode();
instance.setTypeDefinition(td);
instance.setName(name.childrenAsString());
model.addNodes(instance);
process = true;
}
if (td instanceof ComponentType) {
ComponentInstance instance = factory.createComponentInstance();
instance.setTypeDefinition(td);
instance.setName(name.childrenAsString());
pending.add(instance);
process = true;
}
if (td instanceof ChannelType) {
Channel instance = factory.createChannel();
instance.setTypeDefinition(td);
instance.setName(name.childrenAsString());
model.addHubs(instance);
process = true;
}
if (td instanceof GroupType) {
Group instance = factory.createGroup();
instance.setTypeDefinition(td);
instance.setName(name.childrenAsString());
model.addGroups(instance);
process = true;
}
return process;
}
}