com.ly.invoker.builder.compiler.Compiler Maven / Gradle / Ivy
package com.ly.invoker.builder.compiler;
import com.ly.invoker.builder.template.Template;
import com.ly.invoker.builder.validator.Validator;
import com.ly.invoker.core.ICoordinator;
import com.ly.invoker.core.IRouter;
import com.ly.invoker.core.ISelector;
import com.ly.invoker.core.ISingleSelector;
import com.ly.invoker.core.coordinator.Coordinator;
import com.ly.invoker.core.handler.Handler;
import com.ly.invoker.core.handler.HandlerFunction;
import com.ly.invoker.core.payload.Path;
import com.ly.invoker.core.payload.Payload;
import com.ly.invoker.core.router.NameRouter;
import com.ly.invoker.core.router.VersionRouter;
import com.ly.invoker.core.stack.StackElement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Compiler {
private final Validator validator;
private final List elements = new ArrayList<>();
private final Coordinator coordinator;
private final LinkedList stack;
private final LinkedList path;
public Compiler(String structure) {
coordinator = new Coordinator();
this.stack = new LinkedList<>();
path = new LinkedList<>();
validator = new Validator(structure);
}
public Compiler(Template template) {
this(template.structure().toString());
}
public void compile(Context context) {
stack.clear();
path.clear();
elements.clear();
validator.reset();
for (Object element : context.elements()) {
validate(element);
}
newStack(coordinator);
for (Element element : elements) {
switch (element.getType()) {
case NAME_ROUTER:
case VERSION_ROUTER:
case HANDLER:
helper(element);
break;
case LP:
helper(element);
newStack(stack.peekFirst().get(1));
break;
case RP:
stack.removeFirst();
break;
}
}
context.reset();
}
public Coordinator coordinator() {
return coordinator;
}
public void validate(Object element) {
if (element instanceof Element) {
Element e = (Element) element;
validator.validate(e);
elements.add(e);
} else if (element instanceof Context) {
Context c = (Context) element;
for (Object e : c.elements()) {
validate(e);
}
}
}
private void helper(Element element) {
ISelector next = null;
StackElement current = stack.peekFirst();
if (current.get(0) == current.get(1)) {
next = ((Coordinator) current.get(0)).root();
if (next == null) {
next = product(element);
((ICoordinator) current.get(0)).setRoot(next);
}
} else if (current.get(1) instanceof IRouter) {
IRouter r = current.get(1);
String p = path.pollFirst();
if (!r.has(p)) {
next = product(element);
r.add(p, next);
} else {
next = r.route(new Payload().setPath(new Path(new String[]{p})));
}
} else if (current.get(1) instanceof ISingleSelector) {
ISingleSelector s = current.get(1);
next = s.next();
if (next == null) {
next = product(element);
s.setNext(next);
}
}
switch (element.getType()) {
case NAME_ROUTER:
case VERSION_ROUTER:
path.addFirst((String) element.getValue());
}
check(next, element);
current.setIndex(1, next);
}
private void check(ISelector selector, Element element) {
if (selector instanceof Handler) {
Handler h = (Handler) selector;
if (h.isEmpty() && !element.isEmpty()) {
h.setFunction((HandlerFunction) element.getValue());
}
}
}
private ISelector product(Element element) {
switch (element.getType()) {
case NAME_ROUTER:
return new NameRouter();
case VERSION_ROUTER:
return new VersionRouter();
case HANDLER:
return Handler.of((HandlerFunction) element.getValue());
}
return new Coordinator();
}
private void newStack(ICoordinator coordinator) {
if (coordinator == null) {
coordinator = new Coordinator();
}
stack.addFirst(new StackElement(coordinator, coordinator));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy