Skip to content
Snippets Groups Projects
Commit 1962851c authored by René Schöne's avatar René Schöne
Browse files

WIP: Choose protocol at runtime (not in DSL).

- changed semantics of ViaTest slightly (setting same value for inputBoth does not change to newly send value as the "FromMqtt-" and "FromRest-" part is not prepended, and therefore it stays the same)
parent 14fa0734
Branches
No related tags found
No related merge requests found
Pipeline #7561 passed
Showing
with 390 additions and 418 deletions
...@@ -24,44 +24,37 @@ aspect Analysis { ...@@ -24,44 +24,37 @@ aspect Analysis {
} }
// --- isAlreadyDefined --- // --- isAlreadyDefined ---
syn boolean TokenEndpointDefinition.isAlreadyDefined() { syn boolean TokenEndpointDefinition.isAlreadyDefined() = lookupTokenEndpointDefinitions(getToken()).size() > 1;
java.util.List<TokenEndpointDefinition> definitions = lookupTokenEndpointDefinitions(getToken());
java.util.Set<String> protocols = definitions
.stream()
.map(TokenEndpointDefinition::protocol)
.collect(java.util.stream.Collectors.toSet());
return definitions.size() > protocols.size();
}
syn boolean DependencyDefinition.isAlreadyDefined() = lookupDependencyDefinition(getSource().containingTypeDecl(), getID()) != this; syn boolean DependencyDefinition.isAlreadyDefined() = lookupDependencyDefinition(getSource().containingTypeDecl(), getID()) != this;
// --- protocol --- // // --- protocol ---
syn String TokenEndpointDefinition.protocol(); // syn String TokenEndpointDefinition.protocol();
eq ReceiveFromMqttDefinition.protocol() = "mqtt"; // eq ReceiveFromMqttDefinition.protocol() = "mqtt";
eq SendToMqttDefinition.protocol() = "mqtt"; // eq SendToMqttDefinition.protocol() = "mqtt";
eq ReceiveFromRestDefinition.protocol() = "rest"; // eq ReceiveFromRestDefinition.protocol() = "rest";
eq SendToRestDefinition.protocol() = "rest"; // eq SendToRestDefinition.protocol() = "rest";
// --- usesPROTOCOL ---
syn boolean RagConnect.usesMqtt() = !mqttEndpointDefinitions().isEmpty();
syn boolean RagConnect.usesRest() = !restEndpointDefinitions().isEmpty();
// --- mqttEndpointDefinitions --- // // --- usesPROTOCOL ---
coll java.util.List<TokenEndpointDefinition> RagConnect.mqttEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect; // syn boolean RagConnect.usesMqtt() = !mqttEndpointDefinitions().isEmpty();
ReceiveFromMqttDefinition contributes this // syn boolean RagConnect.usesRest() = !restEndpointDefinitions().isEmpty();
to RagConnect.mqttEndpointDefinitions()
for ragconnect();
SendToMqttDefinition contributes this
to RagConnect.mqttEndpointDefinitions()
for ragconnect();
// --- restEndpointDefinitions --- // // --- mqttEndpointDefinitions ---
coll java.util.List<TokenEndpointDefinition> RagConnect.restEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect; // coll java.util.List<TokenEndpointDefinition> RagConnect.mqttEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect;
ReceiveFromRestDefinition contributes this // ReceiveFromMqttDefinition contributes this
to RagConnect.restEndpointDefinitions() // to RagConnect.mqttEndpointDefinitions()
for ragconnect(); // for ragconnect();
SendToRestDefinition contributes this // SendToMqttDefinition contributes this
to RagConnect.restEndpointDefinitions() // to RagConnect.mqttEndpointDefinitions()
for ragconnect(); // for ragconnect();
//
// // --- restEndpointDefinitions ---
// coll java.util.List<TokenEndpointDefinition> RagConnect.restEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect;
// ReceiveFromRestDefinition contributes this
// to RagConnect.restEndpointDefinitions()
// for ragconnect();
// SendToRestDefinition contributes this
// to RagConnect.restEndpointDefinitions()
// for ragconnect();
syn boolean MappingDefinitionType.assignableTo(JavaTypeUse target); syn boolean MappingDefinitionType.assignableTo(JavaTypeUse target);
eq JavaMappingDefinitionType.assignableTo(JavaTypeUse target) = getType().assignableTo(target); eq JavaMappingDefinitionType.assignableTo(JavaTypeUse target) = getType().assignableTo(target);
......
//TypeComponentMustache ; //TypeComponentMustache ;
//rel TypeComponentMustache.TypeComponent -> TypeComponent ; //rel TypeComponentMustache.TypeComponent -> TypeComponent ;
MRagConnect ::= ReceiveDefinition:MReceiveDefinition* PushSendDefinition:MSendDefinition* PullSendDefinition:MSendDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*; MRagConnect ::= ReceiveDefinition:MReceiveDefinition* SendDefinition:MSendDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*;
abstract MEndpointDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*; abstract MEndpointDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*;
MReceiveDefinition : MEndpointDefinition; MReceiveDefinition : MEndpointDefinition;
MSendDefinition : MEndpointDefinition; MSendDefinition : MEndpointDefinition;
......
...@@ -7,13 +7,8 @@ rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*; ...@@ -7,13 +7,8 @@ rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*;
abstract TokenEndpointDefinition : EndpointDefinition; abstract TokenEndpointDefinition : EndpointDefinition;
rel TokenEndpointDefinition.Token -> TokenComponent; rel TokenEndpointDefinition.Token -> TokenComponent;
abstract ReceiveTokenEndpointDefinition : TokenEndpointDefinition; ReceiveTokenEndpointDefinition : TokenEndpointDefinition;
abstract SendTokenEndpointDefinition : TokenEndpointDefinition; SendTokenEndpointDefinition : TokenEndpointDefinition;
ReceiveFromMqttDefinition : ReceiveTokenEndpointDefinition;
SendToMqttDefinition : SendTokenEndpointDefinition;
ReceiveFromRestDefinition : ReceiveTokenEndpointDefinition;
SendToRestDefinition : SendTokenEndpointDefinition;
DependencyDefinition ::= <ID>; DependencyDefinition ::= <ID>;
rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*; rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
......
...@@ -2,4 +2,6 @@ aspect Configuration { ...@@ -2,4 +2,6 @@ aspect Configuration {
public static boolean ASTNode.loggingEnabledForReads = false; public static boolean ASTNode.loggingEnabledForReads = false;
public static boolean ASTNode.loggingEnabledForWrites = false; public static boolean ASTNode.loggingEnabledForWrites = false;
public static TypeDecl ASTNode.rootNode; public static TypeDecl ASTNode.rootNode;
public static boolean ASTNode.usesMqtt;
public static boolean ASTNode.usesRest;
} }
...@@ -34,25 +34,24 @@ aspect AttributesForMustache { ...@@ -34,25 +34,24 @@ aspect AttributesForMustache {
eq MRagConnect.getChild().mqttHandlerField() = mqttHandlerField(); eq MRagConnect.getChild().mqttHandlerField() = mqttHandlerField();
eq MRagConnect.getRootTypeComponent(int i).isFirst() = i == 0; eq MRagConnect.getRootTypeComponent(int i).isFirst() = i == 0;
syn boolean MRagConnect.usesMqtt() = getRagConnect().usesMqtt(); syn String MRagConnect.closeMethod() = "ragconnectCloseConnections";
// syn boolean MRagConnect.usesMqtt() = getRagConnect().usesMqtt();
syn String MRagConnect.mqttHandlerAttribute() = "_mqttHandler"; syn String MRagConnect.mqttHandlerAttribute() = "_mqttHandler";
syn String MRagConnect.mqttHandlerField() = "_mqttHandler"; syn String MRagConnect.mqttHandlerField() = "_mqttHandler";
syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost"; // syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost";
syn String MRagConnect.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady"; syn String MRagConnect.mqttSetupWaitUntilReadyMethod() = "ragconnectSetupMqttWaitUntilReady";
syn String MRagConnect.mqttCloseMethod() = "MqttCloseConnections";
syn boolean MRagConnect.usesRest() = getRagConnect().usesRest(); // syn boolean MRagConnect.usesRest() = getRagConnect().usesRest();
syn String MRagConnect.restHandlerAttribute() = "_restHandler"; syn String MRagConnect.restHandlerAttribute() = "_restHandler";
syn String MRagConnect.restHandlerField() = "_restHandler"; syn String MRagConnect.restHandlerField() = "_restHandler";
syn String MRagConnect.restSetPortMethod() = "RestSetPort"; // syn String MRagConnect.restSetPortMethod() = "RestSetPort";
syn String MRagConnect.restCloseMethod() = "RestCloseConnections";
// --- MEndpointDefinition --- // --- MEndpointDefinition ---
syn String MEndpointDefinition.preemptiveExpectedValue(); syn String MEndpointDefinition.preemptiveExpectedValue();
syn String MEndpointDefinition.preemptiveReturn(); syn String MEndpointDefinition.preemptiveReturn();
syn TokenEndpointDefinition MEndpointDefinition.endpointDef(); syn TokenEndpointDefinition MEndpointDefinition.endpointDef();
syn String MEndpointDefinition.firstInputVarName(); syn String MEndpointDefinition.firstInputVarName();
syn String MEndpointDefinition.newConnectionMethod(); // syn String MEndpointDefinition.newConnectionMethod();
eq MEndpointDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1; eq MEndpointDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1;
eq MEndpointDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix(); eq MEndpointDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix();
...@@ -61,21 +60,21 @@ aspect AttributesForMustache { ...@@ -61,21 +60,21 @@ aspect AttributesForMustache {
inh String MEndpointDefinition.mqttHandlerAttribute(); inh String MEndpointDefinition.mqttHandlerAttribute();
inh String MEndpointDefinition.restHandlerAttribute(); inh String MEndpointDefinition.restHandlerAttribute();
syn String MEndpointDefinition.connectParameterName() { syn String MEndpointDefinition.connectParameterName() = "uriString";
switch (endpointDef().protocol()) { // switch (endpointDef().protocol()) {
case "mqtt": return "topic"; // case "mqtt": return "topic";
case "rest": return "path"; // case "rest": return "path";
default: return null; // default: return null;
} // }
} // }
syn String MEndpointDefinition.handlerAttribute() { // syn String MEndpointDefinition.handlerAttribute() {
switch (endpointDef().protocol()) { // switch (endpointDef().protocol()) {
case "mqtt": return mqttHandlerAttribute(); // case "mqtt": return mqttHandlerAttribute();
case "rest": return restHandlerAttribute(); // case "rest": return restHandlerAttribute();
default: return null; // default: return null;
} // }
} // }
syn String MEndpointDefinition.connectMethod() = "connect" + tokenName() + (ragconnect().lookupTokenEndpointDefinitions(token()).size() > 1 ? "Via" + capitalize(endpointDef().protocol()) : ""); syn String MEndpointDefinition.connectMethod() = "connect" + tokenName();
syn TokenComponent MEndpointDefinition.token() = endpointDef().getToken(); syn TokenComponent MEndpointDefinition.token() = endpointDef().getToken();
syn boolean MEndpointDefinition.alwaysApply() = endpointDef().getAlwaysApply(); syn boolean MEndpointDefinition.alwaysApply() = endpointDef().getAlwaysApply();
syn String MEndpointDefinition.resultVarPrefix() = "result"; // we do not need "_" here, because methodName begins with one syn String MEndpointDefinition.resultVarPrefix() = "result"; // we do not need "_" here, because methodName begins with one
...@@ -112,39 +111,39 @@ aspect AttributesForMustache { ...@@ -112,39 +111,39 @@ aspect AttributesForMustache {
eq MReceiveDefinition.endpointDef() = getReceiveTokenEndpointDefinition(); eq MReceiveDefinition.endpointDef() = getReceiveTokenEndpointDefinition();
eq MReceiveDefinition.firstInputVarName() = "message"; eq MReceiveDefinition.firstInputVarName() = "message";
syn String MReceiveDefinition.newConnectionMethod() { // syn String MReceiveDefinition.newConnectionMethod() {
switch (endpointDef().protocol()) { // switch (endpointDef().protocol()) {
case "mqtt": return "newConnection"; // case "mqtt": return "newConnection";
case "rest": return "newPUTConnection"; // case "rest": return "newPUTConnection";
default: return null; // default: return null;
} // }
} // }
// --- MSendDefinition --- // --- MSendDefinition ---
eq MSendDefinition.preemptiveExpectedValue() = lastValue(); eq MSendDefinition.preemptiveExpectedValue() = lastValue();
eq MSendDefinition.preemptiveReturn() { eq MSendDefinition.preemptiveReturn() = "return false;";
switch (endpointDef().protocol()) { // switch (endpointDef().protocol()) {
case "mqtt": return "return false;"; // case "mqtt": return "return false;";
case "rest": return "throw e;"; // e is Exception variable // case "rest": return "throw e;"; // e is Exception variable
default: return null; // default: return null;
} // }
} // }
eq MSendDefinition.endpointDef() = getSendTokenEndpointDefinition(); eq MSendDefinition.endpointDef() = getSendTokenEndpointDefinition();
eq MSendDefinition.firstInputVarName() = "get" + tokenName() + "()"; eq MSendDefinition.firstInputVarName() = "get" + tokenName() + "()";
syn String MSendDefinition.sendTopic() = "_topic_" + tokenName(); syn String MSendDefinition.sender() = "_sender_" + tokenName();
syn String MSendDefinition.lastValue() = "_lastValue" + tokenName(); syn String MSendDefinition.lastValue() = "_lastValue" + tokenName();
syn String MSendDefinition.updateMethod() = "_update_" + tokenName(); syn String MSendDefinition.updateMethod() = "_update_" + tokenName();
syn String MSendDefinition.writeMethod() = "_writeLastValue_" + tokenName(); syn String MSendDefinition.writeMethod() = "_writeLastValue_" + tokenName();
syn String MSendDefinition.tokenResetMethod() = "get" + tokenName() + "_reset"; syn String MSendDefinition.tokenResetMethod() = "get" + tokenName() + "_reset";
syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush(); // syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush();
syn String MSendDefinition.newConnectionMethod() { // syn String MSendDefinition.newConnectionMethod() {
switch (endpointDef().protocol()) { // switch (endpointDef().protocol()) {
case "mqtt": return null; // case "mqtt": return null;
case "rest": return "newGETConnection"; // case "rest": return "newGETConnection";
default: return null; // default: return null;
} // }
} // }
// --- MMappingDefinition --- // --- MMappingDefinition ---
syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint(); syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint();
...@@ -182,11 +181,7 @@ aspect AttributesForMustache { ...@@ -182,11 +181,7 @@ aspect AttributesForMustache {
for (EndpointDefinition def : getEndpointDefinitionList()) { for (EndpointDefinition def : getEndpointDefinitionList()) {
if (def.isSendTokenEndpointDefinition()) { if (def.isSendTokenEndpointDefinition()) {
SendTokenEndpointDefinition sendDef = def.asSendTokenEndpointDefinition(); SendTokenEndpointDefinition sendDef = def.asSendTokenEndpointDefinition();
if (sendDef.isPush()) { result.addSendDefinition(sendDef.toMustache());
result.addPushSendDefinition(sendDef.toMustache());
} else {
result.addPullSendDefinition(sendDef.toMustache());
}
} else { } else {
result.addReceiveDefinition(def.asReceiveTokenEndpointDefinition().toMustache()); result.addReceiveDefinition(def.asReceiveTokenEndpointDefinition().toMustache());
} }
...@@ -257,9 +252,9 @@ aspect AttributesForMustache { ...@@ -257,9 +252,9 @@ aspect AttributesForMustache {
aspect AspectGeneration { aspect AspectGeneration {
syn boolean SendTokenEndpointDefinition.isPush(); // syn boolean SendTokenEndpointDefinition.isPush();
eq SendToMqttDefinition.isPush() = true; // eq SendToMqttDefinition.isPush() = true;
eq SendToRestDefinition.isPush() = false; // eq SendToRestDefinition.isPush() = false;
// --- rootNodeName --- // --- rootNodeName ---
syn String ASTNode.rootNodeName() = rootNode.getName(); syn String ASTNode.rootNodeName() = rootNode.getName();
......
...@@ -116,10 +116,8 @@ aspect Mappings { ...@@ -116,10 +116,8 @@ aspect Mappings {
// --- isSuitableEdgeMapping(def) --- // --- isSuitableEdgeMapping(def) ---
syn boolean TokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def); syn boolean TokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def);
eq ReceiveFromMqttDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isByteArray(); eq ReceiveTokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isByteArray();
eq SendToMqttDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isByteArray(); eq SendTokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isByteArray();
eq ReceiveFromRestDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isString();
eq SendToRestDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isString();
// --- isPrimitiveType --- // --- isPrimitiveType ---
syn boolean TokenComponent.isPrimitiveType() = effectiveJavaTypeUse().isPrimitiveType(); syn boolean TokenComponent.isPrimitiveType() = effectiveJavaTypeUse().isPrimitiveType();
...@@ -145,9 +143,9 @@ aspect Mappings { ...@@ -145,9 +143,9 @@ aspect Mappings {
// --- suitableDefaultMapping --- // --- suitableDefaultMapping ---
syn DefaultMappingDefinition EndpointDefinition.suitableDefaultMapping(); syn DefaultMappingDefinition EndpointDefinition.suitableDefaultMapping();
eq ReceiveFromMqttDefinition.suitableDefaultMapping() { eq ReceiveTokenEndpointDefinition.suitableDefaultMapping() {
String typeName = getMappingList().isEmpty() ? String typeName = getMappingList().isEmpty() ?
getToken().getJavaTypeUse().getName() : getToken().effectiveJavaTypeUse().getName() :
getMappingList().get(0).getFromType().prettyPrint(); getMappingList().get(0).getFromType().prettyPrint();
switch(typeName) { switch(typeName) {
case "int": case "int":
...@@ -166,9 +164,9 @@ aspect Mappings { ...@@ -166,9 +164,9 @@ aspect Mappings {
default: return null; default: return null;
} }
} }
eq SendToMqttDefinition.suitableDefaultMapping() { eq SendTokenEndpointDefinition.suitableDefaultMapping() {
String typeName = getMappingList().isEmpty() ? String typeName = getMappingList().isEmpty() ?
getToken().getJavaTypeUse().getName() : getToken().effectiveJavaTypeUse().getName() :
getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint(); getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint();
switch(typeName) { switch(typeName) {
case "int": case "int":
...@@ -187,54 +185,54 @@ aspect Mappings { ...@@ -187,54 +185,54 @@ aspect Mappings {
default: return null; default: return null;
} }
} }
eq ReceiveFromRestDefinition.suitableDefaultMapping() { // eq ReceiveFromRestDefinition.suitableDefaultMapping() {
String typeName = getMappingList().isEmpty() ? // String typeName = getMappingList().isEmpty() ?
getToken().getJavaTypeUse().getName() : // getToken().getJavaTypeUse().getName() :
getMappingList().get(0).getFromType().prettyPrint(); // getMappingList().get(0).getFromType().prettyPrint();
switch(typeName) { // switch(typeName) {
case "int": // case "int":
case "Integer": return ragconnect().defaultStringToIntMapping(); // case "Integer": return ragconnect().defaultStringToIntMapping();
case "short": // case "short":
case "Short": return ragconnect().defaultStringToShortMapping(); // case "Short": return ragconnect().defaultStringToShortMapping();
case "long": // case "long":
case "Long": return ragconnect().defaultStringToLongMapping(); // case "Long": return ragconnect().defaultStringToLongMapping();
case "float": // case "float":
case "Float": return ragconnect().defaultStringToFloatMapping(); // case "Float": return ragconnect().defaultStringToFloatMapping();
case "double": // case "double":
case "Double": return ragconnect().defaultStringToDoubleMapping(); // case "Double": return ragconnect().defaultStringToDoubleMapping();
case "char": // case "char":
case "Character": return ragconnect().defaultStringToCharMapping(); // case "Character": return ragconnect().defaultStringToCharMapping();
default: return null; // default: return null;
} // }
} // }
eq SendToRestDefinition.suitableDefaultMapping() { // eq SendToRestDefinition.suitableDefaultMapping() {
String typeName = getMappingList().isEmpty() ? // String typeName = getMappingList().isEmpty() ?
getToken().getJavaTypeUse().getName() : // getToken().getJavaTypeUse().getName() :
getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint(); // getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint();
switch(typeName) { // switch(typeName) {
case "int": // case "int":
case "Integer": return ragconnect().defaultIntToStringMapping(); // case "Integer": return ragconnect().defaultIntToStringMapping();
case "short": // case "short":
case "Short": return ragconnect().defaultShortToStringMapping(); // case "Short": return ragconnect().defaultShortToStringMapping();
case "long": // case "long":
case "Long": return ragconnect().defaultLongToStringMapping(); // case "Long": return ragconnect().defaultLongToStringMapping();
case "float": // case "float":
case "Float": return ragconnect().defaultFloatToStringMapping(); // case "Float": return ragconnect().defaultFloatToStringMapping();
case "double": // case "double":
case "Double": return ragconnect().defaultDoubleToStringMapping(); // case "Double": return ragconnect().defaultDoubleToStringMapping();
case "char": // case "char":
case "Character": return ragconnect().defaultCharToStringMapping(); // case "Character": return ragconnect().defaultCharToStringMapping();
default: return null; // default: return null;
} // }
} // }
// --- isByteArray --- // --- isByteArray ---
syn boolean MappingDefinitionType.isByteArray() = false; syn boolean MappingDefinitionType.isByteArray() = false;
eq JavaArrayMappingDefinitionType.isByteArray() = getType().getName().equals("byte"); eq JavaArrayMappingDefinitionType.isByteArray() = getType().getName().equals("byte");
// --- isString --- // // --- isString ---
syn boolean MappingDefinitionType.isString() = false; // syn boolean MappingDefinitionType.isString() = false;
eq JavaMappingDefinitionType.isString() = getType().getName().equals("String"); // eq JavaMappingDefinitionType.isString() = getType().getName().equals("String");
// --- allMappingDefinitions --- // --- allMappingDefinitions ---
syn java.util.List<MappingDefinition> RagConnect.allMappingDefinitions() { syn java.util.List<MappingDefinition> RagConnect.allMappingDefinitions() {
...@@ -255,19 +253,19 @@ aspect Mappings { ...@@ -255,19 +253,19 @@ aspect Mappings {
result.add(defaultDoubleToBytesMapping()); result.add(defaultDoubleToBytesMapping());
result.add(defaultCharToBytesMapping()); result.add(defaultCharToBytesMapping());
result.add(defaultStringToBytesMapping()); result.add(defaultStringToBytesMapping());
// string conversion // // string conversion
result.add(defaultStringToIntMapping()); // result.add(defaultStringToIntMapping());
result.add(defaultStringToShortMapping()); // result.add(defaultStringToShortMapping());
result.add(defaultStringToLongMapping()); // result.add(defaultStringToLongMapping());
result.add(defaultStringToFloatMapping()); // result.add(defaultStringToFloatMapping());
result.add(defaultStringToDoubleMapping()); // result.add(defaultStringToDoubleMapping());
result.add(defaultStringToCharMapping()); // result.add(defaultStringToCharMapping());
result.add(defaultIntToStringMapping()); // result.add(defaultIntToStringMapping());
result.add(defaultShortToStringMapping()); // result.add(defaultShortToStringMapping());
result.add(defaultLongToStringMapping()); // result.add(defaultLongToStringMapping());
result.add(defaultFloatToStringMapping()); // result.add(defaultFloatToStringMapping());
result.add(defaultDoubleToStringMapping()); // result.add(defaultDoubleToStringMapping());
result.add(defaultCharToStringMapping()); // result.add(defaultCharToStringMapping());
return result; return result;
} }
} }
...@@ -31,12 +31,8 @@ EndpointDefinition endpoint_definition ...@@ -31,12 +31,8 @@ EndpointDefinition endpoint_definition
; ;
EndpointDefinition endpoint_definition_type EndpointDefinition endpoint_definition_type
= RECEIVE token_ref {: return new ReceiveFromMqttDefinition().setToken(token_ref); :} = RECEIVE token_ref {: return new ReceiveTokenEndpointDefinition().setToken(token_ref); :}
| RECEIVE token_ref VIA MQTT {: return new ReceiveFromMqttDefinition().setToken(token_ref); :} | SEND token_ref {: return new SendTokenEndpointDefinition().setToken(token_ref); :}
| RECEIVE token_ref VIA REST {: return enableAlwaysApply(new ReceiveFromRestDefinition()).setToken(token_ref); :}
| SEND token_ref {: return new SendToMqttDefinition().setToken(token_ref); :}
| SEND token_ref VIA MQTT {: return new SendToMqttDefinition().setToken(token_ref); :}
| SEND token_ref VIA REST {: return enableAlwaysApply(new SendToRestDefinition()).setToken(token_ref); :}
; ;
TokenComponent token_ref TokenComponent token_ref
......
...@@ -5,6 +5,3 @@ ...@@ -5,6 +5,3 @@
"maps" { return sym(Terminals.MAPS); } "maps" { return sym(Terminals.MAPS); }
"to" { return sym(Terminals.TO); } "to" { return sym(Terminals.TO); }
"as" { return sym(Terminals.AS); } "as" { return sym(Terminals.AS); }
"via" { return sym(Terminals.VIA); }
"mqtt" { return sym(Terminals.MQTT); }
"rest" { return sym(Terminals.REST); }
...@@ -20,10 +20,14 @@ public class Compiler extends AbstractCompiler { ...@@ -20,10 +20,14 @@ public class Compiler extends AbstractCompiler {
// private ValueOption optionOutputDir; // private ValueOption optionOutputDir;
private ValueOption optionRootNode; private ValueOption optionRootNode;
private ValueOption optionProtocols;
private BooleanOption optionVerbose; private BooleanOption optionVerbose;
private BooleanOption optionLogReads; private BooleanOption optionLogReads;
private BooleanOption optionLogWrites; private BooleanOption optionLogWrites;
private static final String OPTION_PROTOCOL_MQTT = "mqtt";
private static final String OPTION_PROTOCOL_REST = "rest";
public Compiler() { public Compiler() {
super("ragconnect", true); super("ragconnect", true);
} }
...@@ -61,10 +65,10 @@ public class Compiler extends AbstractCompiler { ...@@ -61,10 +65,10 @@ public class Compiler extends AbstractCompiler {
printMessage("Writing output files"); printMessage("Writing output files");
final List<String> handlers = new ArrayList<>(); final List<String> handlers = new ArrayList<>();
if (ragConnect.usesMqtt()) { if (ASTNode.usesMqtt) {
handlers.add("MqttHandler.jadd"); handlers.add("MqttHandler.jadd");
} }
if (ragConnect.usesRest()) { if (ASTNode.usesRest) {
handlers.add("RestHandler.jadd"); handlers.add("RestHandler.jadd");
} }
// copy handlers into outputDir // copy handlers into outputDir
...@@ -138,6 +142,12 @@ public class Compiler extends AbstractCompiler { ...@@ -138,6 +142,12 @@ public class Compiler extends AbstractCompiler {
new ValueOption("rootNode", "root node in the base grammar.") new ValueOption("rootNode", "root node in the base grammar.")
.acceptAnyValue() .acceptAnyValue()
.needsValue(true)); .needsValue(true));
optionProtocols = addOption(
new ValueOption("protocols", "Protocols to enable")
.acceptMultipleValues(true)
.addDefaultValue(OPTION_PROTOCOL_MQTT, "Enable MQTT")
.addAcceptedValue(OPTION_PROTOCOL_REST, "Enable REST")
);
optionVerbose = addOption( optionVerbose = addOption(
new BooleanOption("verbose", "Print more messages while compiling.") new BooleanOption("verbose", "Print more messages while compiling.")
.defaultValue(false)); .defaultValue(false));
...@@ -181,6 +191,8 @@ public class Compiler extends AbstractCompiler { ...@@ -181,6 +191,8 @@ public class Compiler extends AbstractCompiler {
ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration); ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration);
ASTNode.loggingEnabledForReads = optionLogReads.value(); ASTNode.loggingEnabledForReads = optionLogReads.value();
ASTNode.loggingEnabledForWrites = optionLogWrites.value(); ASTNode.loggingEnabledForWrites = optionLogWrites.value();
ASTNode.usesMqtt = optionProtocols.hasValue(OPTION_PROTOCOL_MQTT);
ASTNode.usesRest = optionProtocols.hasValue(OPTION_PROTOCOL_REST);
return ragConnect; return ragConnect;
} }
......
package org.jastadd.ragconnect.compiler;
import beaver.Parser;
import org.jastadd.ragconnect.ast.*;
import org.jastadd.ragconnect.parser.RagConnectParser;
import org.jastadd.ragconnect.scanner.RagConnectScanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Testing Ros2Rag without parser.
*
* @author rschoene - Initial contribution
*/
public class SimpleMain {
// --- just testing byte[] conversion ---
public static void testing() {
System.out.println("---");
try {
Class<?> clazz = Class.forName("java.util.List");
System.out.println("clazz.getName() = " + clazz.getName());
System.out.println(Integer.class.isAssignableFrom(Integer.class));
System.out.println(new SimpleJavaTypeUse("int").assignableTo(new SimpleJavaTypeUse("Integer")));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("---");
byte[] bytes;
int i = 1;
double d = 2.3d;
float f = 4.2f;
short sh = 13;
long l = 7L;
String s = "Hello";
char c = 'a';
Integer ii = Integer.valueOf(1);
if (!ii.equals(i)) throw new AssertionError("Ints not equal");
// int to byte
ByteBuffer i2b = ByteBuffer.allocate(4);
i2b.putInt(i);
bytes = i2b.array();
// byte to int
ByteBuffer b2i = ByteBuffer.wrap(bytes);
int actual_i = b2i.getInt();
if (i != actual_i) throw new AssertionError("Ints not equal");
// double to byte
ByteBuffer d2b = ByteBuffer.allocate(8);
d2b.putDouble(d);
bytes = d2b.array();
// byte to double
ByteBuffer b2d = ByteBuffer.wrap(bytes);
double actual_d = b2d.getDouble();
if (d != actual_d) throw new AssertionError("Doubles not equal");
// float to byte
ByteBuffer f2b = ByteBuffer.allocate(4);
f2b.putFloat(f);
bytes = f2b.array();
// byte to float
ByteBuffer b2f = ByteBuffer.wrap(bytes);
float actual_f = b2f.getFloat();
if (f != actual_f) throw new AssertionError("Floats not equal");
// short to byte
ByteBuffer sh2b = ByteBuffer.allocate(2);
sh2b.putShort(sh);
bytes = sh2b.array();
// byte to short
ByteBuffer b2sh = ByteBuffer.wrap(bytes);
short actual_sh = b2sh.getShort();
if (sh != actual_sh) throw new AssertionError("Shorts not equal");
// long to byte
ByteBuffer l2b = ByteBuffer.allocate(8);
l2b.putLong(l);
bytes = l2b.array();
// byte to long
ByteBuffer b2l = ByteBuffer.wrap(bytes);
long actual_l = b2l.getLong();
if (l != actual_l) throw new AssertionError("Longs not equal");
// String to byte
bytes = s.getBytes();
// byte to String
String actual_s = new String(bytes);
if (!s.equals(actual_s)) throw new AssertionError("Strings not equal");
// char to byte
ByteBuffer c2b = ByteBuffer.allocate(2);
c2b.putChar(c);
bytes = c2b.array();
// byte to char
ByteBuffer b2c = ByteBuffer.wrap(bytes);
char actual_c = b2c.getChar();
if (c != actual_c) throw new AssertionError("Floats not equal");
}
public static void main(String[] args) {
testing();
// createManualAST();
}
private static void createManualAST() {
RagConnect model = new RagConnect();
Program program = parseProgram(Paths.get("ros2rag.starter","src", "main", "jastadd", "RobotModel.relast"));
model.setProgram(program);
MappingDefinition mappingDefinition = new MappingDefinition();
mappingDefinition.setID("PoseToPosition");
mappingDefinition.setFromType(makeMappingDefinitionType("int"));
mappingDefinition.setFromVariableName("x");
mappingDefinition.setToType(makeMappingDefinitionType("Position"));
mappingDefinition.setContent(" pose.position.x += sqrt(.5 * size.x)\n" +
" MAP round(2)\n" +
" x = x / 100\n" +
" IGNORE_IF_SAME\n" +
" ;");
model.addMappingDefinition(mappingDefinition);
ReceiveFromMqttDefinition receiveFromMqttDefinition = new ReceiveFromMqttDefinition();
receiveFromMqttDefinition.setAlwaysApply(false);
receiveFromMqttDefinition.setToken(TokenComponent.createRef("Link.CurrentPosition"));
receiveFromMqttDefinition.addMapping(mappingDefinition);
model.addEndpointDefinition(receiveFromMqttDefinition);
model.treeResolveAll();
for (ErrorMessage error : model.errors()) {
System.err.println(error);
}
System.out.println(model.generateAspect("Model"));
}
private static MappingDefinitionType makeMappingDefinitionType(String type) {
JavaMappingDefinitionType result = new JavaMappingDefinitionType();
result.setType(new SimpleJavaTypeUse(type));
return result;
}
private static Program parseProgram(Path path) {
try (BufferedReader reader = Files.newBufferedReader(path)) {
RagConnectScanner scanner = new RagConnectScanner(reader);
RagConnectParser parser = new RagConnectParser();
GrammarFile grammarFile = (GrammarFile) parser.parse(scanner);
Program program = new Program();
program.addGrammarFile(grammarFile);
return program;
} catch (IOException | Parser.Exception e) {
e.printStackTrace();
}
return null;
}
}
aspect MqttHandler { import java.io.IOException;
import java.util.concurrent.TimeUnit;aspect MqttHandler {
public class MqttServerHandler {
private final java.util.Map<String, MqttHandler> handlers = new java.util.HashMap<>();
private long time;
private java.util.concurrent.TimeUnit unit;
private String name;
public MqttServerHandler() {
this("RagConnect");
}
public MqttServerHandler(String name) {
this.name = name;
setupWaitUntilReady(1, TimeUnit.SECONDS);
}
public void setupWaitUntilReady(long time, java.util.concurrent.TimeUnit unit) {
this.time = time;
this.unit = unit;
}
public MqttHandler resolveHandler(java.net.URI uri) throws IOException {
MqttHandler handler = handlers.get(uri.getHost());
if (handler == null) {
// first connect to that server
handler = new MqttHandler();
if (uri.getPort() == -1) {
handler.setHost(uri.getHost());
} else {
handler.setHost(uri.getHost(), uri.getPort());
}
handlers.put(uri.getHost(), handler);
}
handler.waitUntilReady(this.time, this.unit);
return handler;
}
public boolean newConnection(java.net.URI uri, java.util.function.Consumer<byte[]> callback) throws IOException {
return resolveHandler(uri).newConnection(extractTopic(uri), callback);
}
public void publish(java.net.URI uri, byte[] bytes) throws IOException {
resolveHandler(uri).publish(extractTopic(uri), bytes);
}
public void publish(java.net.URI uri, byte[] bytes, boolean retain) throws IOException {
resolveHandler(uri).publish(extractTopic(uri), bytes, retain);
}
public void publish(java.net.URI uri, byte[] bytes,
org.fusesource.mqtt.client.QoS qos, boolean retain) throws IOException {
resolveHandler(uri).publish(extractTopic(uri), bytes, qos, retain);
}
private String extractTopic(java.net.URI uri) {
String path = uri.getPath();
if (path.charAt(0) == '/') {
path = path.substring(1);
}
return path;
}
public void close() {
for (MqttHandler handler : handlers.values()) {
handler.close();
}
}
}
/** /**
* Helper class to receive updates via MQTT and use callbacks to handle those messages. * Helper class to receive updates via MQTT and use callbacks to handle those messages.
* *
...@@ -14,10 +83,8 @@ public class MqttHandler { ...@@ -14,10 +83,8 @@ public class MqttHandler {
private java.net.URI host; private java.net.URI host;
/** The connection to the MQTT broker. */ /** The connection to the MQTT broker. */
private org.fusesource.mqtt.client.CallbackConnection connection; private org.fusesource.mqtt.client.CallbackConnection connection;
/** Whether we are subscribed to the topics yet */ /** Whether we are connected yet */
private final java.util.concurrent.locks.Condition readyCondition; private final java.util.concurrent.CountDownLatch readyLatch;
private final java.util.concurrent.locks.Lock readyLock;
private boolean ready;
private boolean sendWelcomeMessage = true; private boolean sendWelcomeMessage = true;
private org.fusesource.mqtt.client.QoS qos; private org.fusesource.mqtt.client.QoS qos;
/** Dispatch knowledge */ /** Dispatch knowledge */
...@@ -31,9 +98,7 @@ public class MqttHandler { ...@@ -31,9 +98,7 @@ public class MqttHandler {
this.name = java.util.Objects.requireNonNull(name, "Name must be set"); this.name = java.util.Objects.requireNonNull(name, "Name must be set");
this.logger = org.apache.logging.log4j.LogManager.getLogger(MqttHandler.class); this.logger = org.apache.logging.log4j.LogManager.getLogger(MqttHandler.class);
this.callbacks = new java.util.HashMap<>(); this.callbacks = new java.util.HashMap<>();
this.readyLock = new java.util.concurrent.locks.ReentrantLock(); this.readyLatch = new java.util.concurrent.CountDownLatch(1);
this.readyCondition = readyLock.newCondition();
this.ready = false;
this.qos = org.fusesource.mqtt.client.QoS.AT_LEAST_ONCE; this.qos = org.fusesource.mqtt.client.QoS.AT_LEAST_ONCE;
} }
...@@ -144,13 +209,7 @@ public class MqttHandler { ...@@ -144,13 +209,7 @@ public class MqttHandler {
} }
private void setReady() { private void setReady() {
try { readyLatch.countDown();
readyLock.lock();
ready = true;
readyCondition.signalAll();
} finally {
readyLock.unlock();
}
} }
private void throwIf(java.util.concurrent.atomic.AtomicReference<Throwable> error) throws java.io.IOException { private void throwIf(java.util.concurrent.atomic.AtomicReference<Throwable> error) throws java.io.IOException {
...@@ -163,12 +222,15 @@ public class MqttHandler { ...@@ -163,12 +222,15 @@ public class MqttHandler {
this.qos = qos; this.qos = qos;
} }
public void newConnection(String topic, java.util.function.Consumer<byte[]> callback) { public boolean newConnection(String topic, java.util.function.Consumer<byte[]> callback) {
if (!ready) { if (readyLatch.getCount() > 0) {
// should maybe be something more kind than throwing an exception here System.err.println("Handler not ready");
throw new IllegalStateException("Updater not ready"); return false;
// // should maybe be something more kind than throwing an exception here
// throw new IllegalStateException("Updater not ready");
} }
// register callback // register callback
logger.debug("new connection for {}", topic);
if (callbacks.get(topic) == null) { if (callbacks.get(topic) == null) {
callbacks.put(topic, new java.util.ArrayList<>()); callbacks.put(topic, new java.util.ArrayList<>());
...@@ -189,6 +251,7 @@ public class MqttHandler { ...@@ -189,6 +251,7 @@ public class MqttHandler {
}); });
} }
callbacks.get(topic).add(callback); callbacks.get(topic).add(callback);
return true;
} }
/** /**
...@@ -202,15 +265,9 @@ public class MqttHandler { ...@@ -202,15 +265,9 @@ public class MqttHandler {
*/ */
public boolean waitUntilReady(long time, java.util.concurrent.TimeUnit unit) { public boolean waitUntilReady(long time, java.util.concurrent.TimeUnit unit) {
try { try {
readyLock.lock(); return readyLatch.await(time, unit);
if (ready) {
return true;
}
return readyCondition.await(time, unit);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} finally {
readyLock.unlock();
} }
return false; return false;
} }
...@@ -253,7 +310,7 @@ public class MqttHandler { ...@@ -253,7 +310,7 @@ public class MqttHandler {
@Override @Override
public void onFailure(Throwable value) { public void onFailure(Throwable value) {
logger.warn("Could not publish on topic '{}'", topic); logger.warn("Could not publish on topic '{}'", topic, value);
} }
}); });
}); });
......
aspect RestHandler { import java.util.concurrent.TimeUnit;aspect RestHandler {
public class RestServerHandler {
private static final int DEFAULT_PORT = 4567;
private final java.util.Map<Integer, RestHandler> handlers = new java.util.HashMap<>();
private String name;
public RestServerHandler() {
this("RagConnect");
}
public RestServerHandler(String name) {
this.name = name;
}
private RestHandler resolveHandler(java.net.URI uri) {
int port = uri.getPort() != -1 ? uri.getPort() : DEFAULT_PORT;
RestHandler handler = handlers.get(port);
if (handler == null) {
// first connect to that server
handler = new RestHandler();
handler.setPort(port);
handlers.put(port, handler);
}
return handler;
}
public boolean newPUTConnection(java.net.URI uri, java.util.function.Consumer<String> callback) {
resolveHandler(uri).newPUTConnection(uri.getPath(), callback);
return true;
}
public boolean newGETConnection(java.net.URI uri, SupplierWithException<String> supplier) {
resolveHandler(uri).newGETConnection(uri.getPath(), supplier);
return true;
}
public void close() {
for (RestHandler handler : handlers.values()) {
handler.close();
}
}
}
/** /**
* Helper class to receive updates and publishes information via REST. * Helper class to receive updates and publishes information via REST.
* @author rschoene - Initial contribution * @author rschoene - Initial contribution
...@@ -54,7 +95,7 @@ public class RestHandler { ...@@ -54,7 +95,7 @@ public class RestHandler {
if (errors.isEmpty()) { if (errors.isEmpty()) {
return "OK"; return "OK";
} else { } else {
return makeError(response, 500, errors.stream().collect(java.util.stream.Collectors.joining("\n", "The folloing errors happened: [", "]"))); return makeError(response, 500, errors.stream().collect(java.util.stream.Collectors.joining("\n", "The following error(s) happened: [", "]")));
} }
}); });
} }
...@@ -79,7 +120,7 @@ public class RestHandler { ...@@ -79,7 +120,7 @@ public class RestHandler {
return message; return message;
} }
public void start() { private void start() {
logger.info("Starting REST server at {}", this.port); logger.info("Starting REST server at {}", this.port);
spark.Spark.port(this.port); spark.Spark.port(this.port);
spark.Spark.init(); spark.Spark.init();
......
String scheme,host, path;
java.net.URI uri;
try {
uri = new java.net.URI({{connectParameterName}});
scheme = uri.getScheme();
host = uri.getHost();
path = uri.getPath();
} catch (java.net.URISyntaxException e) {
System.err.println(e.getMessage()); // Maybe re-throw error?
return false;
}
aspect RagConnectHandler {
interface RagConnectHandler<T> {
boolean connectReceive(String path, java.util.function.Consumer<T> callback);
boolean sendPush(String path, T value);
boolean connectSendPull(String path, SupplierWithException<T> supplier);
}
}
aspect MQTT { aspect MQTT {
private String {{rootNodeName}}.MqttName() { return "RagConnectMQTT"; } private String {{rootNodeName}}.MqttName() { return "RagConnectMQTT"; }
private MqttHandler {{rootNodeName}}.{{mqttHandlerField}} = new MqttHandler(MqttName()); private MqttServerHandler {{rootNodeName}}.{{mqttHandlerField}} = new MqttServerHandler(MqttName());
public void {{rootNodeName}}.{{mqttSetHostMethod}}(String host) throws java.io.IOException {
{{mqttHandlerField}}.setHost(host);
}
public void {{rootNodeName}}.{{mqttSetHostMethod}}(String host, int port) throws java.io.IOException {
{{mqttHandlerField}}.setHost(host, port);
}
public boolean {{rootNodeName}}.{{mqttWaitUntilReadyMethod}}(long time, java.util.concurrent.TimeUnit unit) {
return {{mqttHandlerField}}.waitUntilReady(time, unit);
}
public void {{rootNodeName}}.{{mqttCloseMethod}}() { public void {{rootNodeName}}.{{mqttSetupWaitUntilReadyMethod}}(long time, java.util.concurrent.TimeUnit unit) {
{{mqttHandlerField}}.close(); {{mqttHandlerField}}.setupWaitUntilReady(time, unit);
} }
{{#getRootTypeComponents}} {{#getRootTypeComponents}}
{{#first}}inh MqttHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}} {{#first}}inh MqttServerHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}}
eq {{rootNodeName}}.get{{name}}().{{mqttHandlerAttribute}}() = {{mqttHandlerField}}; eq {{rootNodeName}}.get{{name}}().{{mqttHandlerAttribute}}() = {{mqttHandlerField}};
{{/getRootTypeComponents}} {{/getRootTypeComponents}}
{{^getRootTypeComponents}} {{^getRootTypeComponents}}
syn MqttHandler {{rootNodeName}}.{{mqttHandlerAttribute}}() = {{mqttHandlerField}}; syn MqttServerHandler {{rootNodeName}}.{{mqttHandlerAttribute}}() = {{mqttHandlerField}};
{{/getRootTypeComponents}} {{/getRootTypeComponents}}
} }
{{#usesMqtt}} {{#usesMqtt}}{{> mqtt}}{{/usesMqtt}}
{{> mqtt}} {{#usesRest}}{{> rest}}{{/usesRest}}
{{/usesMqtt}}
{{#usesRest}}
{{> rest}}
{{/usesRest}}
aspect ROS2RAG { aspect ROS2RAG {
public void {{rootNodeName}}.{{closeMethod}}() {
{{#usesMqtt}}{{mqttHandlerField}}.close();{{/usesMqtt}}
{{#usesRest}}{{restHandlerField}}.close();{{/usesRest}}
}
{{#ReceiveDefinitions}} {{#ReceiveDefinitions}}
{{> receiveDefinition}} {{> receiveDefinition}}
{{/ReceiveDefinitions}} {{/ReceiveDefinitions}}
{{#PushSendDefinitions}} {{#SendDefinitions}}
{{> sendDefinitionPush}} {{> sendDefinition}}
{{/PushSendDefinitions}} {{/SendDefinitions}}
{{#PullSendDefinitions}}
{{> sendDefinitionPull}}
{{/PullSendDefinitions}}
{{#MappingDefinitions}} {{#MappingDefinitions}}
{{> mappingDefinition}} {{> mappingDefinition}}
......
public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}) { public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}) throws java.io.IOException {
{{handlerAttribute}}().{{newConnectionMethod}}({{connectParameterName}}, message -> { {{>handleUri}}
java.util.function.Consumer<byte[]> consumer = message -> {
{{> mappingApplication}} {{> mappingApplication}}
{{#loggingEnabledForReads}} {{#loggingEnabledForReads}}
System.out.println("[Receive] " + {{connectParameterName}} + " -> {{tokenName}} = " + {{lastResult}}); System.out.println("[Receive] " + {{connectParameterName}} + " -> {{tokenName}} = " + {{lastResult}});
{{/loggingEnabledForReads}} {{/loggingEnabledForReads}}
set{{tokenName}}({{lastResult}}); set{{tokenName}}({{lastResult}});
};
switch (scheme) {
{{#usesMqtt}}
case "mqtt": return {{mqttHandlerAttribute}}().newConnection(uri, consumer);
{{/usesMqtt}}
{{#usesRest}}
case "rest": return {{restHandlerAttribute}}().newPUTConnection(uri, input -> {
consumer.accept(input.getBytes());
}); });
{{/usesRest}}
default:
System.err.println("Unknown protocol '" + scheme + "'.");
return false;
}
} }
aspect REST { aspect REST {
private String {{rootNodeName}}.RestName() { return "RagConnectREST"; } private String {{rootNodeName}}.RestName() { return "RagConnectREST"; }
private RestHandler {{rootNodeName}}.{{restHandlerField}} = new RestHandler(RestName()); private RestServerHandler {{rootNodeName}}.{{restHandlerField}} = new RestServerHandler(RestName());
public void {{rootNodeName}}.{{restSetPortMethod}}(int port) {
{{restHandlerField}}.setPort(port);
}
public void {{rootNodeName}}.{{restCloseMethod}}() {
{{restHandlerField}}.close();
}
{{#getRootTypeComponents}} {{#getRootTypeComponents}}
{{#first}}inh RestHandler ASTNode.{{restHandlerAttribute}}();{{/first}} {{#first}}inh RestServerHandler ASTNode.{{restHandlerAttribute}}();{{/first}}
eq {{rootNodeName}}.get{{name}}().{{restHandlerAttribute}}() = {{restHandlerField}}; eq {{rootNodeName}}.get{{name}}().{{restHandlerAttribute}}() = {{restHandlerField}};
{{/getRootTypeComponents}} {{/getRootTypeComponents}}
{{^getRootTypeComponents}} {{^getRootTypeComponents}}
syn RestHandler {{rootNodeName}}.{{restHandlerAttribute}}() = {{restHandlerField}}; syn RestServerHandler {{rootNodeName}}.{{restHandlerAttribute}}() = {{restHandlerField}};
{{/getRootTypeComponents}} {{/getRootTypeComponents}}
} }
private Runnable {{parentTypeName}}.{{sender}} = null;
private byte[] {{parentTypeName}}.{{lastValue}} = null;
public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) {
{{>handleUri}}
switch (scheme) {
{{#usesMqtt}}
case "mqtt":
// MqttHandler handler = {{mqttHandlerAttribute}}().resolveHandler(uri);{{!optimize later}}
{{sender}} = () -> {
{{#loggingEnabledForWrites}}
System.out.println("[Send] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{connectParameterName}});
{{/loggingEnabledForWrites}}
try {
{{mqttHandlerAttribute}}().publish(uri, {{lastValue}});
} catch (java.io.IOException e) {
e.printStackTrace();
}
};
{{updateMethod}}();
if (writeCurrentValue) {
{{writeMethod}}();
}
break;
{{/usesMqtt}}
{{#usesRest}}
case "rest":
{{restHandlerAttribute}}().newGETConnection(uri, () -> {
{{updateMethod}}();
return new String({{lastValue}});
});
break;
{{/usesRest}}
default:
System.err.println("Unknown protocol '" + scheme + "'.");
return false;
}
return true;
}
protected boolean {{parentTypeName}}.{{updateMethod}}() {
{{tokenResetMethod}}();
{{> mappingApplication}}
{{lastValue}} = {{lastResult}};
// normally we would return true here. unless no connect method was called so far to initialize {{sender}} yet
return {{sender}} != null;
}
protected void {{parentTypeName}}.{{writeMethod}}() {
{{sender}}.run();
}
public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) {
{{handlerAttribute}}().{{newConnectionMethod}}({{connectParameterName}}, () -> {
{{tokenResetMethod}}();
{{> mappingApplication}}
return {{lastResult}};
});
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment