Select Git revision
CATKIN_IGNORE
MinimalMain.java 14.68 KiB
package de.tudresden.inf.st.mrc;
import de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper;
import de.tudresden.inf.st.mrc.ast.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import static java.util.concurrent.TimeUnit.SECONDS;
/**
* Minimal main.
*
* @author rschoene - Initial contribution
*/
@SuppressWarnings("CommentedOutCode")
public class MinimalMain {
private static final Logger logger = LogManager.getLogger(MinimalMain.class);
private static final String TOPIC_FOR_INPUT = "topic/for/input";
private static final String TOPIC_URI_FOR_INPUT = "mqtt://localhost/" + TOPIC_FOR_INPUT;
private static MqttHandler publisher;
// static class MinimalReceiver implements Receiver {
// List<String> latestAttributes;
// Receiver oldReceiver;
//
// MinimalReceiver(Receiver oldReceiver) {
// this.oldReceiver = oldReceiver;
// reset();
// }
//
// void reset() {
// latestAttributes = new ArrayList<>();
// }
//
// @SuppressWarnings("rawtypes")
// @Override
// public void accept(ASTState.Trace.Event event, ASTNode node, String attribute, Object params, Object value) {
// oldReceiver.accept(event, node, attribute, params, value);
// logger.info("event: {}, node: {}, attribute: {}, params: {}, value: {},", event, node, attribute, params, value);
// latestAttributes.add(attribute);
// }
// }
// static MinimalReceiver receiver = null;
public static void main(String[] args) throws Exception {
publisher = new MqttHandler("publisher").setHost("localhost");
publisher.waitUntilReady(2, SECONDS);
publisher.publish("---", ("Start at " + Instant.now()).getBytes());
// mainIncremental();
// mainSimpleTree();
mainRelationalTree();
}
private static void mainIncremental() throws Exception {
// byte[] -> bool: input[0] == (byte) 1;
// bool -> byte[]: java.nio.ByteBuffer.allocate(1).put((byte) 1).array();
boolean success;
A normalA = addNewA(true);
// enableTracing(normalA);
B b1 = normalA.getB(0);
B b2 = normalA.getB(1);
// a.OutputOnA -> a.Input
normalA.addDependencyA(normalA);
// b1.OutputOnB -> a.Input
b1.addDependencyB(normalA);
// b2.OutputOnB -> a.Input
b2.addDependencyB(normalA);
normalA.connectInput(TOPIC_URI_FOR_INPUT);
normalA.connectOutputOnA("mqtt://localhost/normalA/out", true);
b1.connectOutputOnB("mqtt://localhost/normalA/b1/out", true);
b2.connectOutputOnB("mqtt://localhost/normalA/b2/out", false);
A aWithNoDependency = addNewA(false);
// enableTracing(aWithNoDependency);
aWithNoDependency.connectInput(TOPIC_URI_FOR_INPUT);
aWithNoDependency.connectOutputOnA("mqtt://localhost/aNoDep/out", true);
aWithNoDependency.getC(0).connectOutputOnC("mqtt://localhost/aNoDep/c1/out", true);
aWithNoDependency.getC(1).connectOutputOnC("mqtt://localhost/aNoDep/c2/out", false);
Dumper.read(normalA).dumpAsPNG(Paths.get("image.png"));
describedWait(1, "Publish 2");
publisher.publish(TOPIC_FOR_INPUT, "2".getBytes());
describedWait(1, "Publish 21");
publisher.publish(TOPIC_FOR_INPUT, "21".getBytes());
describedWait(1, "Publish 22 and 23");
publisher.publish(TOPIC_FOR_INPUT, "22".getBytes());
publisher.publish(TOPIC_FOR_INPUT, "23".getBytes());
describedWait(2, "Disconnect normalA");
success = normalA.disconnectInput(TOPIC_URI_FOR_INPUT);
logger.info("disconnect success: {}", success);
describedWait(2, "Publish 4");
publisher.publish(TOPIC_FOR_INPUT, "4".getBytes());
describedWait(1, "Disconnect aNoDep");
success = aWithNoDependency.disconnectInput(TOPIC_URI_FOR_INPUT);
logger.info("disconnect success: {}", success);
describedWait(1, "Publish 6");
publisher.publish(TOPIC_FOR_INPUT, "6".getBytes());
describedWait(1, "Connect aNormal again");
success = normalA.connectInput(TOPIC_URI_FOR_INPUT);
logger.info("connect success: {}", success);
describedWait(1, "Publish 8");
publisher.publish(TOPIC_FOR_INPUT, "8".getBytes());
describedWait(1, "Publish 81");
publisher.publish(TOPIC_FOR_INPUT, "81".getBytes());
describedWait(1, "Connect aNoDep again");
success = aWithNoDependency.connectInput(TOPIC_URI_FOR_INPUT);
logger.info("connect success: {}", success);
describedWait(1, "Publish 10");
publisher.publish(TOPIC_FOR_INPUT, "10".getBytes());
describedWait(1, "Publish 101");
publisher.publish(TOPIC_FOR_INPUT, "101".getBytes());
// while (true) {}
// System.out.println("[Enter] to exit");
// Scanner scanner = new Scanner(System.in);
// scanner.nextLine();
// SECONDS.sleep(15);
describedWait(0, "End");
}
private static void describedWait(long seconds, String description) throws InterruptedException {
SECONDS.sleep(seconds);
logger.info("--- {} ---", description);
publisher.publish("---", description.getBytes());
}
private static A addNewA(boolean useB) {
A result = new A();
result.setInput("1");
if (useB) {
B b1 = new B();
B b2 = new B();
result.addB(b1);
result.addB(b2);
} else {
C c1 = new C();
C c2 = new C();
result.addC(c1);
result.addC(c2);
}
return result;
}
private static void testTree() throws IOException, SerializationException, DeserializationException {
A root = new A();
root.setInput("123");
java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
{
com.fasterxml.jackson.core.JsonFactory factory = new com.fasterxml.jackson.core.JsonFactory();
com.fasterxml.jackson.core.JsonGenerator generator = factory.createGenerator(outputStream, com.fasterxml.jackson.core.JsonEncoding.UTF8);
root.serialize(generator);
generator.flush();
}
String content = outputStream.toString();
System.out.println(content);
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
com.fasterxml.jackson.core.JsonFactory factory = new com.fasterxml.jackson.core.JsonFactory();
com.fasterxml.jackson.core.JsonParser parser = factory.createParser(content);
A result = A.deserialize((com.fasterxml.jackson.databind.JsonNode)mapper.readTree(parser));
parser.close();
logger.info("result.getInput() = " + result.getInput());
logger.info("result.getD().getID() = " + result.getD().getID());
}
private static void mainSimpleTree() throws IOException, InterruptedException {
String uriString = "mqtt://localhost/normalA/d/out";
Root root = new Root();
root.ragconnectSetupMqttWaitUntilReady(2, SECONDS);
A sender = new A();
root.addA(sender);
sender.setInput("123");
A receiver = new A();
root.addA(receiver);
receiver.connectReading(uriString);
sender.connectOutputOnA("mqtt://localhost/normalA/out", true);
sender.connectD(uriString, true);
describedWait(1, "initial value");
logger.info("receiver.getReading().getID() = " + receiver.getReading().getID());
sender.getD().setID("abc");
describedWait(1, "after setID (does not work)");
logger.info("receiver.getReading().getID() = " + receiver.getReading().getID());
sender.setInput("def");
describedWait(1, "after setInput");
logger.info("receiver.getReading().getID() = " + receiver.getReading().getID());
}
private static void mainRelationalTree() throws IOException, InterruptedException {
final String mqttUriString = "mqtt://localhost/alfa";
Root root1ForSender = new Root();
root1ForSender.ragconnectSetupMqttWaitUntilReady(2, SECONDS);
SenderRoot senderRoot = createSenderRoot();
root1ForSender.addSenderRoot(senderRoot);
senderRoot.connectAlfa(mqttUriString, false);
Root root2ForReceiver = new Root();
root2ForReceiver.ragconnectSetupMqttWaitUntilReady(2, SECONDS);
ReceiverRoot receiverRoot = createReceiverRoot();
root2ForReceiver.addReceiverRoot(receiverRoot);
receiverRoot.connectAlfa(mqttUriString);
Dumper.read(senderRoot).includeNonterminalAttributes("Alfa").dumpAsPNG(Paths.get("00-initial-sender.png"));
Dumper.read(receiverRoot).dumpAsPNG(Paths.get("00-initial-receiver.png"));
senderRoot.setInput(1);
describedWait(1, "after setting input to 1");
printAlfa(true, senderRoot, receiverRoot);
printAlfa(false, senderRoot, receiverRoot);
Dumper.read(senderRoot).includeNonterminalAttributes("Alfa").dumpAsPNG(Paths.get("01-after-1-sender.png"));
Dumper.read(receiverRoot).dumpAsPNG(Paths.get("01-after-1-receiver.png"));
printAlfa(true, senderRoot, receiverRoot);
printAlfa(false, senderRoot, receiverRoot);
senderRoot.setInput(2);
describedWait(1, "after setting input to 2");
printAlfa(true, senderRoot, receiverRoot);
printAlfa(false, senderRoot, receiverRoot);
Dumper.read(senderRoot).includeNonterminalAttributes("Alfa").dumpAsPNG(Paths.get("02-after-2-sender.png"));
Dumper.read(receiverRoot).dumpAsPNG(Paths.get("02-after-2-receiver.png"));
printAlfa(true, senderRoot, receiverRoot);
printAlfa(false, senderRoot, receiverRoot);
}
private static SenderRoot createSenderRoot() {
SenderRoot result = new SenderRoot();
SenderSubTree subTree = new SenderSubTree();
result.setSenderSubTree(subTree);
templateCreation(result::addBravo, result::addCharlie, result::addDelta, subTree::addHotel);
return result;
}
private static ReceiverRoot createReceiverRoot() {
ReceiverRoot result = new ReceiverRoot();
ReceiverSubTree subTree = new ReceiverSubTree();
result.setReceiverSubTree(subTree);
templateCreation(result::addBravo, result::addCharlie, result::addDelta, subTree::addHotel);
return result;
}
private static void templateCreation(AddBravo addBravo, AddCharlie addCharlie, AddDelta addDelta, AddHotel addHotel) {
for (int i = 0; i < 4; i++) {
addBravo.accept(new Bravo(i));
addCharlie.accept(new Charlie(i));
addDelta.accept(new Delta(i));
addHotel.accept(new Hotel(i));
}
}
interface AddBravo { void accept(Bravo b); }
interface AddCharlie { void accept(Charlie b); }
interface AddDelta { void accept(Delta b); }
interface AddHotel { void accept(Hotel b); }
private static void printAlfa(boolean isSender, SenderRoot senderRoot, ReceiverRoot receiverRoot) {
final String name;
final String tick;
final Alfa alfa;
final Iterable<Delta> deltaList;
final Iterable<Hotel> hotelList;
if (isSender) {
name = "sender";
tick = " >-";
alfa = senderRoot.getAlfa();
deltaList = senderRoot.getDeltaList();
hotelList = senderRoot.getSenderSubTree().getHotelList();
} else {
name = "receiver";
tick = " <-";
alfa = receiverRoot.getAlfa();
deltaList = receiverRoot.getDeltaList();
hotelList = receiverRoot.getReceiverSubTree().getHotelList();
}
// also dump AST
StringBuilder sb = new StringBuilder();
printNode(alfa.getParent(), "", sb);
logger.info("\n{}", sb.toString());
logger.info("Checking Alfa\n" +
"{}: {} in {}\n" +
tick + " Myself: {}\n" +
// tick + " MyBravo: {}\n" +
// tick + " MultiBravoList: {}\n" +
// tick + " MidiDelta: {} (MidiDelta.getMidiAlfa(): {})\n" +
// tick + " DeltaList: {}\n" +
tick + " MyEcho: {}\n" +
tick + " EchoList.MyFoxtrot: {}\n" +
tick + " MultiEchoList: {}\n" +
tick + " FoxtrotList.MyAlfa: {}\n" +
tick + " FoxtrotList.MyHotel: {}\n" +
tick + " MidiGolf: {} (MidiGolf.getMidiAlfa(): {})\n" +
tick + " GolfList (id -> alfa.id): {}\n" +
// tick + " MyHotel: {}\n" +
// tick + " MultiHotelList: {}\n" +
// tick + " HotelList: {}" +
"{}", // just to make swapping of params easier (all have a comma at the end)
name, alfa, alfa.getParent(),
nameAndHash(alfa.getMyself()),
// nameAndHash(alfa.getMyBravo()),
// printNameableList(alfa.getMultiBravoList()),
// nameAndHash(alfa.getMidiDelta()), alfa.getMidiDelta().getMidiAlfa(),
// printOptionalList(deltaList, Delta::hasMidiAlfa, Delta::getMidiAlfa),
nameAndHash(alfa.getMyEcho()),
printOptionalList(alfa.getEchoList(), Echo::hasMyFoxtrot, Echo::getMyFoxtrot),
printNameableList(alfa.getMultiEchoList()),
printOptionalList(alfa.getFoxtrotList(), Foxtrot::hasMyAlfa, Foxtrot::getMyAlfa),
printOptionalList(alfa.getFoxtrotList(), Foxtrot::hasMyHotel, Foxtrot::getMyHotel),
nameAndHash(alfa.getMidiGolf()), nameAndHash(alfa.getMidiGolf().getMidiAlfa()),
printOptionalList(alfa.getGolfList(), Golf::hasMidiAlfa, Golf::getMidiAlfa),
// nameAndHash(alfa.getMyHotel()),
// printNameableList(alfa.getMultiHotelList()),
// printNameableList(toList(hotelList)),
""
);
}
private static List<? extends Nameable> toList(Iterable<Hotel> hotelList) {
List<Hotel> result = new ArrayList<>();
hotelList.forEach(result::add);
return result;
}
private static String printNameableList(List<? extends Nameable> nameableList) {
return nameableList.stream().map(MinimalMain::nameAndHash).collect(Collectors.joining(",", "[", "]"));
}
private static <T extends Nameable> String printOptionalList(Iterable<T> tIterable, Function<T, Boolean> hasChild, Function<T, Nameable> getChild) {
StringBuilder sb = new StringBuilder();
for (T t : tIterable) {
sb.append(nameAndHash(t))
.append(" -> ")
.append(hasChild.apply(t) ? nameAndHash(getChild.apply(t)) : "/")
.append(", ");
}
return sb.toString();
}
private static String nameAndHash(Nameable nameable) {
return nameable.getID() + " (@" + Integer.toHexString(nameable.hashCode()) + ")";
}
private static void printNode(ASTNode<?> node, String indent, StringBuilder sb) {
if (node.isNameable()) {
sb.append(indent)
.append("- ")
.append(node.getClass().getSimpleName())
.append(nameAndHash((Nameable) node))
.append("\n");
}
for (ASTNode<?> child : node.astChildren()) {
printNode(child, node instanceof JastAddList ? indent : indent + " |", sb);
}
}
// private static void enableTracing(ASTNode<?> node) {
// if (node.trace().getReceiver() != null && node.trace().getReceiver() instanceof MinimalReceiver) {
// System.out.println("*** receiver already set up ***");
// } else {
// System.out.println("*** activate receiver ***");
// receiver = new MinimalReceiver(node.trace().getReceiver());
// node.trace().setReceiver(receiver);
// }
// }
}