diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag index 769d283301b8fb29064c8030bfee6f9fb5e433da..1fc2e2f44baccd87c861eaad699d739866a3aae0 100644 --- a/src/main/jastadd/Analysis.jrag +++ b/src/main/jastadd/Analysis.jrag @@ -24,44 +24,37 @@ aspect Analysis { } // --- isAlreadyDefined --- - syn boolean TokenEndpointDefinition.isAlreadyDefined() { - 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 TokenEndpointDefinition.isAlreadyDefined() = lookupTokenEndpointDefinitions(getToken()).size() > 1; syn boolean DependencyDefinition.isAlreadyDefined() = lookupDependencyDefinition(getSource().containingTypeDecl(), getID()) != this; - // --- protocol --- - syn String TokenEndpointDefinition.protocol(); - eq ReceiveFromMqttDefinition.protocol() = "mqtt"; - eq SendToMqttDefinition.protocol() = "mqtt"; - eq ReceiveFromRestDefinition.protocol() = "rest"; - eq SendToRestDefinition.protocol() = "rest"; - - // --- usesPROTOCOL --- - syn boolean RagConnect.usesMqtt() = !mqttEndpointDefinitions().isEmpty(); - syn boolean RagConnect.usesRest() = !restEndpointDefinitions().isEmpty(); +// // --- protocol --- +// syn String TokenEndpointDefinition.protocol(); +// eq ReceiveFromMqttDefinition.protocol() = "mqtt"; +// eq SendToMqttDefinition.protocol() = "mqtt"; +// eq ReceiveFromRestDefinition.protocol() = "rest"; +// eq SendToRestDefinition.protocol() = "rest"; - // --- mqttEndpointDefinitions --- - coll java.util.List<TokenEndpointDefinition> RagConnect.mqttEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect; - ReceiveFromMqttDefinition contributes this - to RagConnect.mqttEndpointDefinitions() - for ragconnect(); - SendToMqttDefinition contributes this - to RagConnect.mqttEndpointDefinitions() - for ragconnect(); +// // --- usesPROTOCOL --- +// syn boolean RagConnect.usesMqtt() = !mqttEndpointDefinitions().isEmpty(); +// syn boolean RagConnect.usesRest() = !restEndpointDefinitions().isEmpty(); - // --- 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(); +// // --- mqttEndpointDefinitions --- +// coll java.util.List<TokenEndpointDefinition> RagConnect.mqttEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect; +// ReceiveFromMqttDefinition contributes this +// to RagConnect.mqttEndpointDefinitions() +// for ragconnect(); +// SendToMqttDefinition contributes this +// to RagConnect.mqttEndpointDefinitions() +// 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); eq JavaMappingDefinitionType.assignableTo(JavaTypeUse target) = getType().assignableTo(target); diff --git a/src/main/jastadd/MustacheNodes.relast b/src/main/jastadd/MustacheNodes.relast index d2d611798005c45e810ebfeddfa6c767b36167e4..ceead524746145c07d1ea980bcd534e25979073b 100644 --- a/src/main/jastadd/MustacheNodes.relast +++ b/src/main/jastadd/MustacheNodes.relast @@ -1,7 +1,7 @@ //TypeComponentMustache ; //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*; MReceiveDefinition : MEndpointDefinition; MSendDefinition : MEndpointDefinition; diff --git a/src/main/jastadd/RagConnect.relast b/src/main/jastadd/RagConnect.relast index 2729b85c23a87725a954e00d303caf1414cf9267..accc617714ff6bdd24a22831ea84e5d93e6a15b8 100644 --- a/src/main/jastadd/RagConnect.relast +++ b/src/main/jastadd/RagConnect.relast @@ -7,13 +7,8 @@ rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*; abstract TokenEndpointDefinition : EndpointDefinition; rel TokenEndpointDefinition.Token -> TokenComponent; -abstract ReceiveTokenEndpointDefinition : TokenEndpointDefinition; -abstract SendTokenEndpointDefinition : TokenEndpointDefinition; - -ReceiveFromMqttDefinition : ReceiveTokenEndpointDefinition; -SendToMqttDefinition : SendTokenEndpointDefinition; -ReceiveFromRestDefinition : ReceiveTokenEndpointDefinition; -SendToRestDefinition : SendTokenEndpointDefinition; +ReceiveTokenEndpointDefinition : TokenEndpointDefinition; +SendTokenEndpointDefinition : TokenEndpointDefinition; DependencyDefinition ::= <ID>; rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*; diff --git a/src/main/jastadd/backend/Configuration.jadd b/src/main/jastadd/backend/Configuration.jadd index d4f5b43f27cb329f1ff82318c6f383f0f69ebbd6..8d3b16c3f99014408c6aefa5655201d222c3d892 100644 --- a/src/main/jastadd/backend/Configuration.jadd +++ b/src/main/jastadd/backend/Configuration.jadd @@ -2,4 +2,6 @@ aspect Configuration { public static boolean ASTNode.loggingEnabledForReads = false; public static boolean ASTNode.loggingEnabledForWrites = false; public static TypeDecl ASTNode.rootNode; + public static boolean ASTNode.usesMqtt; + public static boolean ASTNode.usesRest; } diff --git a/src/main/jastadd/backend/Generation.jadd b/src/main/jastadd/backend/Generation.jadd index ff948334b793fc4930585ee5705285187b7c2606..0bb7e85f7a8f3486c2dd1900e1c800d77aead1d1 100644 --- a/src/main/jastadd/backend/Generation.jadd +++ b/src/main/jastadd/backend/Generation.jadd @@ -34,25 +34,24 @@ aspect AttributesForMustache { eq MRagConnect.getChild().mqttHandlerField() = mqttHandlerField(); 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.mqttHandlerField() = "_mqttHandler"; - syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost"; - syn String MRagConnect.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady"; - syn String MRagConnect.mqttCloseMethod() = "MqttCloseConnections"; +// syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost"; + syn String MRagConnect.mqttSetupWaitUntilReadyMethod() = "ragconnectSetupMqttWaitUntilReady"; - syn boolean MRagConnect.usesRest() = getRagConnect().usesRest(); +// syn boolean MRagConnect.usesRest() = getRagConnect().usesRest(); syn String MRagConnect.restHandlerAttribute() = "_restHandler"; syn String MRagConnect.restHandlerField() = "_restHandler"; - syn String MRagConnect.restSetPortMethod() = "RestSetPort"; - syn String MRagConnect.restCloseMethod() = "RestCloseConnections"; +// syn String MRagConnect.restSetPortMethod() = "RestSetPort"; // --- MEndpointDefinition --- syn String MEndpointDefinition.preemptiveExpectedValue(); syn String MEndpointDefinition.preemptiveReturn(); syn TokenEndpointDefinition MEndpointDefinition.endpointDef(); syn String MEndpointDefinition.firstInputVarName(); - syn String MEndpointDefinition.newConnectionMethod(); +// syn String MEndpointDefinition.newConnectionMethod(); eq MEndpointDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1; eq MEndpointDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix(); @@ -61,21 +60,21 @@ aspect AttributesForMustache { inh String MEndpointDefinition.mqttHandlerAttribute(); inh String MEndpointDefinition.restHandlerAttribute(); - syn String MEndpointDefinition.connectParameterName() { - switch (endpointDef().protocol()) { - case "mqtt": return "topic"; - case "rest": return "path"; - default: return null; - } - } - syn String MEndpointDefinition.handlerAttribute() { - switch (endpointDef().protocol()) { - case "mqtt": return mqttHandlerAttribute(); - case "rest": return restHandlerAttribute(); - default: return null; - } - } - syn String MEndpointDefinition.connectMethod() = "connect" + tokenName() + (ragconnect().lookupTokenEndpointDefinitions(token()).size() > 1 ? "Via" + capitalize(endpointDef().protocol()) : ""); + syn String MEndpointDefinition.connectParameterName() = "uriString"; +// switch (endpointDef().protocol()) { +// case "mqtt": return "topic"; +// case "rest": return "path"; +// default: return null; +// } +// } +// syn String MEndpointDefinition.handlerAttribute() { +// switch (endpointDef().protocol()) { +// case "mqtt": return mqttHandlerAttribute(); +// case "rest": return restHandlerAttribute(); +// default: return null; +// } +// } + syn String MEndpointDefinition.connectMethod() = "connect" + tokenName(); syn TokenComponent MEndpointDefinition.token() = endpointDef().getToken(); syn boolean MEndpointDefinition.alwaysApply() = endpointDef().getAlwaysApply(); syn String MEndpointDefinition.resultVarPrefix() = "result"; // we do not need "_" here, because methodName begins with one @@ -112,39 +111,39 @@ aspect AttributesForMustache { eq MReceiveDefinition.endpointDef() = getReceiveTokenEndpointDefinition(); eq MReceiveDefinition.firstInputVarName() = "message"; - syn String MReceiveDefinition.newConnectionMethod() { - switch (endpointDef().protocol()) { - case "mqtt": return "newConnection"; - case "rest": return "newPUTConnection"; - default: return null; - } - } +// syn String MReceiveDefinition.newConnectionMethod() { +// switch (endpointDef().protocol()) { +// case "mqtt": return "newConnection"; +// case "rest": return "newPUTConnection"; +// default: return null; +// } +// } // --- MSendDefinition --- eq MSendDefinition.preemptiveExpectedValue() = lastValue(); - eq MSendDefinition.preemptiveReturn() { - switch (endpointDef().protocol()) { - case "mqtt": return "return false;"; - case "rest": return "throw e;"; // e is Exception variable - default: return null; - } - } + eq MSendDefinition.preemptiveReturn() = "return false;"; +// switch (endpointDef().protocol()) { +// case "mqtt": return "return false;"; +// case "rest": return "throw e;"; // e is Exception variable +// default: return null; +// } +// } eq MSendDefinition.endpointDef() = getSendTokenEndpointDefinition(); 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.updateMethod() = "_update_" + tokenName(); syn String MSendDefinition.writeMethod() = "_writeLastValue_" + tokenName(); syn String MSendDefinition.tokenResetMethod() = "get" + tokenName() + "_reset"; - syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush(); - syn String MSendDefinition.newConnectionMethod() { - switch (endpointDef().protocol()) { - case "mqtt": return null; - case "rest": return "newGETConnection"; - default: return null; - } - } +// syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush(); +// syn String MSendDefinition.newConnectionMethod() { +// switch (endpointDef().protocol()) { +// case "mqtt": return null; +// case "rest": return "newGETConnection"; +// default: return null; +// } +// } // --- MMappingDefinition --- syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint(); @@ -182,11 +181,7 @@ aspect AttributesForMustache { for (EndpointDefinition def : getEndpointDefinitionList()) { if (def.isSendTokenEndpointDefinition()) { SendTokenEndpointDefinition sendDef = def.asSendTokenEndpointDefinition(); - if (sendDef.isPush()) { - result.addPushSendDefinition(sendDef.toMustache()); - } else { - result.addPullSendDefinition(sendDef.toMustache()); - } + result.addSendDefinition(sendDef.toMustache()); } else { result.addReceiveDefinition(def.asReceiveTokenEndpointDefinition().toMustache()); } @@ -257,9 +252,9 @@ aspect AttributesForMustache { aspect AspectGeneration { - syn boolean SendTokenEndpointDefinition.isPush(); - eq SendToMqttDefinition.isPush() = true; - eq SendToRestDefinition.isPush() = false; +// syn boolean SendTokenEndpointDefinition.isPush(); +// eq SendToMqttDefinition.isPush() = true; +// eq SendToRestDefinition.isPush() = false; // --- rootNodeName --- syn String ASTNode.rootNodeName() = rootNode.getName(); diff --git a/src/main/jastadd/backend/Mappings.jrag b/src/main/jastadd/backend/Mappings.jrag index 0410cc289d9e69fc27b343ac162cdd6b60bcb9d5..fb1239bfdd8e7ca0af60ea2382eff8dcfb22ed60 100644 --- a/src/main/jastadd/backend/Mappings.jrag +++ b/src/main/jastadd/backend/Mappings.jrag @@ -116,10 +116,8 @@ aspect Mappings { // --- isSuitableEdgeMapping(def) --- syn boolean TokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def); - eq ReceiveFromMqttDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isByteArray(); - eq SendToMqttDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isByteArray(); - eq ReceiveFromRestDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isString(); - eq SendToRestDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isString(); + eq ReceiveTokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isByteArray(); + eq SendTokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isByteArray(); // --- isPrimitiveType --- syn boolean TokenComponent.isPrimitiveType() = effectiveJavaTypeUse().isPrimitiveType(); @@ -145,9 +143,9 @@ aspect Mappings { // --- suitableDefaultMapping --- syn DefaultMappingDefinition EndpointDefinition.suitableDefaultMapping(); - eq ReceiveFromMqttDefinition.suitableDefaultMapping() { + eq ReceiveTokenEndpointDefinition.suitableDefaultMapping() { String typeName = getMappingList().isEmpty() ? - getToken().getJavaTypeUse().getName() : + getToken().effectiveJavaTypeUse().getName() : getMappingList().get(0).getFromType().prettyPrint(); switch(typeName) { case "int": @@ -166,9 +164,9 @@ aspect Mappings { default: return null; } } - eq SendToMqttDefinition.suitableDefaultMapping() { + eq SendTokenEndpointDefinition.suitableDefaultMapping() { String typeName = getMappingList().isEmpty() ? - getToken().getJavaTypeUse().getName() : + getToken().effectiveJavaTypeUse().getName() : getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint(); switch(typeName) { case "int": @@ -187,54 +185,54 @@ aspect Mappings { default: return null; } } - eq ReceiveFromRestDefinition.suitableDefaultMapping() { - String typeName = getMappingList().isEmpty() ? - getToken().getJavaTypeUse().getName() : - getMappingList().get(0).getFromType().prettyPrint(); - switch(typeName) { - case "int": - case "Integer": return ragconnect().defaultStringToIntMapping(); - case "short": - case "Short": return ragconnect().defaultStringToShortMapping(); - case "long": - case "Long": return ragconnect().defaultStringToLongMapping(); - case "float": - case "Float": return ragconnect().defaultStringToFloatMapping(); - case "double": - case "Double": return ragconnect().defaultStringToDoubleMapping(); - case "char": - case "Character": return ragconnect().defaultStringToCharMapping(); - default: return null; - } - } - eq SendToRestDefinition.suitableDefaultMapping() { - String typeName = getMappingList().isEmpty() ? - getToken().getJavaTypeUse().getName() : - getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint(); - switch(typeName) { - case "int": - case "Integer": return ragconnect().defaultIntToStringMapping(); - case "short": - case "Short": return ragconnect().defaultShortToStringMapping(); - case "long": - case "Long": return ragconnect().defaultLongToStringMapping(); - case "float": - case "Float": return ragconnect().defaultFloatToStringMapping(); - case "double": - case "Double": return ragconnect().defaultDoubleToStringMapping(); - case "char": - case "Character": return ragconnect().defaultCharToStringMapping(); - default: return null; - } - } +// eq ReceiveFromRestDefinition.suitableDefaultMapping() { +// String typeName = getMappingList().isEmpty() ? +// getToken().getJavaTypeUse().getName() : +// getMappingList().get(0).getFromType().prettyPrint(); +// switch(typeName) { +// case "int": +// case "Integer": return ragconnect().defaultStringToIntMapping(); +// case "short": +// case "Short": return ragconnect().defaultStringToShortMapping(); +// case "long": +// case "Long": return ragconnect().defaultStringToLongMapping(); +// case "float": +// case "Float": return ragconnect().defaultStringToFloatMapping(); +// case "double": +// case "Double": return ragconnect().defaultStringToDoubleMapping(); +// case "char": +// case "Character": return ragconnect().defaultStringToCharMapping(); +// default: return null; +// } +// } +// eq SendToRestDefinition.suitableDefaultMapping() { +// String typeName = getMappingList().isEmpty() ? +// getToken().getJavaTypeUse().getName() : +// getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint(); +// switch(typeName) { +// case "int": +// case "Integer": return ragconnect().defaultIntToStringMapping(); +// case "short": +// case "Short": return ragconnect().defaultShortToStringMapping(); +// case "long": +// case "Long": return ragconnect().defaultLongToStringMapping(); +// case "float": +// case "Float": return ragconnect().defaultFloatToStringMapping(); +// case "double": +// case "Double": return ragconnect().defaultDoubleToStringMapping(); +// case "char": +// case "Character": return ragconnect().defaultCharToStringMapping(); +// default: return null; +// } +// } // --- isByteArray --- syn boolean MappingDefinitionType.isByteArray() = false; eq JavaArrayMappingDefinitionType.isByteArray() = getType().getName().equals("byte"); - // --- isString --- - syn boolean MappingDefinitionType.isString() = false; - eq JavaMappingDefinitionType.isString() = getType().getName().equals("String"); +// // --- isString --- +// syn boolean MappingDefinitionType.isString() = false; +// eq JavaMappingDefinitionType.isString() = getType().getName().equals("String"); // --- allMappingDefinitions --- syn java.util.List<MappingDefinition> RagConnect.allMappingDefinitions() { @@ -255,19 +253,19 @@ aspect Mappings { result.add(defaultDoubleToBytesMapping()); result.add(defaultCharToBytesMapping()); result.add(defaultStringToBytesMapping()); - // string conversion - result.add(defaultStringToIntMapping()); - result.add(defaultStringToShortMapping()); - result.add(defaultStringToLongMapping()); - result.add(defaultStringToFloatMapping()); - result.add(defaultStringToDoubleMapping()); - result.add(defaultStringToCharMapping()); - result.add(defaultIntToStringMapping()); - result.add(defaultShortToStringMapping()); - result.add(defaultLongToStringMapping()); - result.add(defaultFloatToStringMapping()); - result.add(defaultDoubleToStringMapping()); - result.add(defaultCharToStringMapping()); +// // string conversion +// result.add(defaultStringToIntMapping()); +// result.add(defaultStringToShortMapping()); +// result.add(defaultStringToLongMapping()); +// result.add(defaultStringToFloatMapping()); +// result.add(defaultStringToDoubleMapping()); +// result.add(defaultStringToCharMapping()); +// result.add(defaultIntToStringMapping()); +// result.add(defaultShortToStringMapping()); +// result.add(defaultLongToStringMapping()); +// result.add(defaultFloatToStringMapping()); +// result.add(defaultDoubleToStringMapping()); +// result.add(defaultCharToStringMapping()); return result; } } diff --git a/src/main/jastadd/parser/RagConnect.parser b/src/main/jastadd/parser/RagConnect.parser index 56a8dc4cc7f3396e778a529e981c1aefb302e18b..0432b0df96c44060f6df1d6918a856f62810230d 100644 --- a/src/main/jastadd/parser/RagConnect.parser +++ b/src/main/jastadd/parser/RagConnect.parser @@ -31,12 +31,8 @@ EndpointDefinition endpoint_definition ; EndpointDefinition endpoint_definition_type - = RECEIVE token_ref {: return new ReceiveFromMqttDefinition().setToken(token_ref); :} - | RECEIVE token_ref VIA MQTT {: return new ReceiveFromMqttDefinition().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); :} + = RECEIVE token_ref {: return new ReceiveTokenEndpointDefinition().setToken(token_ref); :} + | SEND token_ref {: return new SendTokenEndpointDefinition().setToken(token_ref); :} ; TokenComponent token_ref diff --git a/src/main/jastadd/scanner/Keywords.flex b/src/main/jastadd/scanner/Keywords.flex index fe8a8141140884f7c53295f76877dd277c41ac4c..5773118d8fda8ffdc536b504aa7056b8784ddfb3 100644 --- a/src/main/jastadd/scanner/Keywords.flex +++ b/src/main/jastadd/scanner/Keywords.flex @@ -5,6 +5,3 @@ "maps" { return sym(Terminals.MAPS); } "to" { return sym(Terminals.TO); } "as" { return sym(Terminals.AS); } -"via" { return sym(Terminals.VIA); } -"mqtt" { return sym(Terminals.MQTT); } -"rest" { return sym(Terminals.REST); } diff --git a/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java b/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java index 5160ab6611f8a8f177555e55e511153b95a9659b..d44ef9e590abd09d3c7d7026c3da2dfe5f29511b 100644 --- a/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java +++ b/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java @@ -20,10 +20,14 @@ public class Compiler extends AbstractCompiler { // private ValueOption optionOutputDir; private ValueOption optionRootNode; + private ValueOption optionProtocols; private BooleanOption optionVerbose; private BooleanOption optionLogReads; private BooleanOption optionLogWrites; + private static final String OPTION_PROTOCOL_MQTT = "mqtt"; + private static final String OPTION_PROTOCOL_REST = "rest"; + public Compiler() { super("ragconnect", true); } @@ -61,10 +65,10 @@ public class Compiler extends AbstractCompiler { printMessage("Writing output files"); final List<String> handlers = new ArrayList<>(); - if (ragConnect.usesMqtt()) { + if (ASTNode.usesMqtt) { handlers.add("MqttHandler.jadd"); } - if (ragConnect.usesRest()) { + if (ASTNode.usesRest) { handlers.add("RestHandler.jadd"); } // copy handlers into outputDir @@ -138,6 +142,12 @@ public class Compiler extends AbstractCompiler { new ValueOption("rootNode", "root node in the base grammar.") .acceptAnyValue() .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( new BooleanOption("verbose", "Print more messages while compiling.") .defaultValue(false)); @@ -181,6 +191,8 @@ public class Compiler extends AbstractCompiler { ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration); ASTNode.loggingEnabledForReads = optionLogReads.value(); ASTNode.loggingEnabledForWrites = optionLogWrites.value(); + ASTNode.usesMqtt = optionProtocols.hasValue(OPTION_PROTOCOL_MQTT); + ASTNode.usesRest = optionProtocols.hasValue(OPTION_PROTOCOL_REST); return ragConnect; } diff --git a/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java b/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java deleted file mode 100644 index 9da13bf479b6fe16be8c935b06cf1e9ad3283308..0000000000000000000000000000000000000000 --- a/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java +++ /dev/null @@ -1,170 +0,0 @@ -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; - } -} diff --git a/src/main/resources/MqttHandler.jadd b/src/main/resources/MqttHandler.jadd index 1161211ffb0b90eaf26c7d27d709d71f7a6369c8..6f40612520cfb97151600dff53c8e0d384ab441e 100644 --- a/src/main/resources/MqttHandler.jadd +++ b/src/main/resources/MqttHandler.jadd @@ -1,4 +1,73 @@ -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. * @@ -14,10 +83,8 @@ public class MqttHandler { private java.net.URI host; /** The connection to the MQTT broker. */ private org.fusesource.mqtt.client.CallbackConnection connection; - /** Whether we are subscribed to the topics yet */ - private final java.util.concurrent.locks.Condition readyCondition; - private final java.util.concurrent.locks.Lock readyLock; - private boolean ready; + /** Whether we are connected yet */ + private final java.util.concurrent.CountDownLatch readyLatch; private boolean sendWelcomeMessage = true; private org.fusesource.mqtt.client.QoS qos; /** Dispatch knowledge */ @@ -31,9 +98,7 @@ public class MqttHandler { this.name = java.util.Objects.requireNonNull(name, "Name must be set"); this.logger = org.apache.logging.log4j.LogManager.getLogger(MqttHandler.class); this.callbacks = new java.util.HashMap<>(); - this.readyLock = new java.util.concurrent.locks.ReentrantLock(); - this.readyCondition = readyLock.newCondition(); - this.ready = false; + this.readyLatch = new java.util.concurrent.CountDownLatch(1); this.qos = org.fusesource.mqtt.client.QoS.AT_LEAST_ONCE; } @@ -144,13 +209,7 @@ public class MqttHandler { } private void setReady() { - try { - readyLock.lock(); - ready = true; - readyCondition.signalAll(); - } finally { - readyLock.unlock(); - } + readyLatch.countDown(); } private void throwIf(java.util.concurrent.atomic.AtomicReference<Throwable> error) throws java.io.IOException { @@ -163,12 +222,15 @@ public class MqttHandler { this.qos = qos; } - public void newConnection(String topic, java.util.function.Consumer<byte[]> callback) { - if (!ready) { - // should maybe be something more kind than throwing an exception here - throw new IllegalStateException("Updater not ready"); + public boolean newConnection(String topic, java.util.function.Consumer<byte[]> callback) { + if (readyLatch.getCount() > 0) { + System.err.println("Handler not ready"); + return false; +// // should maybe be something more kind than throwing an exception here +// throw new IllegalStateException("Updater not ready"); } // register callback + logger.debug("new connection for {}", topic); if (callbacks.get(topic) == null) { callbacks.put(topic, new java.util.ArrayList<>()); @@ -189,6 +251,7 @@ public class MqttHandler { }); } callbacks.get(topic).add(callback); + return true; } /** @@ -202,15 +265,9 @@ public class MqttHandler { */ public boolean waitUntilReady(long time, java.util.concurrent.TimeUnit unit) { try { - readyLock.lock(); - if (ready) { - return true; - } - return readyCondition.await(time, unit); + return readyLatch.await(time, unit); } catch (InterruptedException e) { e.printStackTrace(); - } finally { - readyLock.unlock(); } return false; } @@ -253,7 +310,7 @@ public class MqttHandler { @Override public void onFailure(Throwable value) { - logger.warn("Could not publish on topic '{}'", topic); + logger.warn("Could not publish on topic '{}'", topic, value); } }); }); diff --git a/src/main/resources/RestHandler.jadd b/src/main/resources/RestHandler.jadd index 24118f04c563fe0b44105bfe674e269c76e7466f..f7b1a83304fe7aaebe97d105514c3f192d052aec 100644 --- a/src/main/resources/RestHandler.jadd +++ b/src/main/resources/RestHandler.jadd @@ -1,4 +1,45 @@ -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. * @author rschoene - Initial contribution @@ -54,7 +95,7 @@ public class RestHandler { if (errors.isEmpty()) { return "OK"; } 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 { return message; } - public void start() { + private void start() { logger.info("Starting REST server at {}", this.port); spark.Spark.port(this.port); spark.Spark.init(); diff --git a/src/main/resources/handleUri.mustache b/src/main/resources/handleUri.mustache new file mode 100644 index 0000000000000000000000000000000000000000..a9187f8c610b258b9da28e86da818e13b57d29d5 --- /dev/null +++ b/src/main/resources/handleUri.mustache @@ -0,0 +1,11 @@ + 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; + } diff --git a/src/main/resources/handler.mustache b/src/main/resources/handler.mustache new file mode 100644 index 0000000000000000000000000000000000000000..e89c451007ff309a77297b9b66fe0e20dece73b8 --- /dev/null +++ b/src/main/resources/handler.mustache @@ -0,0 +1,7 @@ +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); +} +} diff --git a/src/main/resources/mqtt.mustache b/src/main/resources/mqtt.mustache index 95b253a9b4b4e46fda738a66499b8e2a7cc3707d..f10ae88139d958d2f4b0a8f4245b64b41e0f1003 100644 --- a/src/main/resources/mqtt.mustache +++ b/src/main/resources/mqtt.mustache @@ -1,26 +1,16 @@ aspect MQTT { private String {{rootNodeName}}.MqttName() { return "RagConnectMQTT"; } - private MqttHandler {{rootNodeName}}.{{mqttHandlerField}} = new MqttHandler(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); - } + private MqttServerHandler {{rootNodeName}}.{{mqttHandlerField}} = new MqttServerHandler(MqttName()); - public void {{rootNodeName}}.{{mqttCloseMethod}}() { - {{mqttHandlerField}}.close(); + public void {{rootNodeName}}.{{mqttSetupWaitUntilReadyMethod}}(long time, java.util.concurrent.TimeUnit unit) { + {{mqttHandlerField}}.setupWaitUntilReady(time, unit); } {{#getRootTypeComponents}} - {{#first}}inh MqttHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}} + {{#first}}inh MqttServerHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}} eq {{rootNodeName}}.get{{name}}().{{mqttHandlerAttribute}}() = {{mqttHandlerField}}; {{/getRootTypeComponents}} {{^getRootTypeComponents}} - syn MqttHandler {{rootNodeName}}.{{mqttHandlerAttribute}}() = {{mqttHandlerField}}; + syn MqttServerHandler {{rootNodeName}}.{{mqttHandlerAttribute}}() = {{mqttHandlerField}}; {{/getRootTypeComponents}} } diff --git a/src/main/resources/ragconnect.mustache b/src/main/resources/ragconnect.mustache index 24e25418d07766f0ac881683080a622687ceff8e..5b12e3fae20555a7fe9055b226ca0cb96bcff8f5 100644 --- a/src/main/resources/ragconnect.mustache +++ b/src/main/resources/ragconnect.mustache @@ -1,21 +1,17 @@ -{{#usesMqtt}} - {{> mqtt}} -{{/usesMqtt}} -{{#usesRest}} - {{> rest}} -{{/usesRest}} +{{#usesMqtt}}{{> mqtt}}{{/usesMqtt}} +{{#usesRest}}{{> rest}}{{/usesRest}} aspect ROS2RAG { + public void {{rootNodeName}}.{{closeMethod}}() { + {{#usesMqtt}}{{mqttHandlerField}}.close();{{/usesMqtt}} + {{#usesRest}}{{restHandlerField}}.close();{{/usesRest}} + } {{#ReceiveDefinitions}} {{> receiveDefinition}} {{/ReceiveDefinitions}} - {{#PushSendDefinitions}} - {{> sendDefinitionPush}} - {{/PushSendDefinitions}} - - {{#PullSendDefinitions}} - {{> sendDefinitionPull}} - {{/PullSendDefinitions}} + {{#SendDefinitions}} + {{> sendDefinition}} + {{/SendDefinitions}} {{#MappingDefinitions}} {{> mappingDefinition}} diff --git a/src/main/resources/receiveDefinition.mustache b/src/main/resources/receiveDefinition.mustache index 31a08c737349b6c2d16f14a0fab50065d2c01a35..62e2bf6faf441fe7c6d700bb8b4daf6168196c3e 100644 --- a/src/main/resources/receiveDefinition.mustache +++ b/src/main/resources/receiveDefinition.mustache @@ -1,9 +1,23 @@ - public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}) { - {{handlerAttribute}}().{{newConnectionMethod}}({{connectParameterName}}, message -> { + public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}) throws java.io.IOException { + {{>handleUri}} + java.util.function.Consumer<byte[]> consumer = message -> { {{> mappingApplication}} {{#loggingEnabledForReads}} System.out.println("[Receive] " + {{connectParameterName}} + " -> {{tokenName}} = " + {{lastResult}}); {{/loggingEnabledForReads}} 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; + } } diff --git a/src/main/resources/rest.mustache b/src/main/resources/rest.mustache index fb77601c38467e0f3f1bd1f01993db410670ce16..6bbde2be4d26e519635c85a6f39f9a18514bfb19 100644 --- a/src/main/resources/rest.mustache +++ b/src/main/resources/rest.mustache @@ -1,18 +1,12 @@ aspect REST { private String {{rootNodeName}}.RestName() { return "RagConnectREST"; } - private RestHandler {{rootNodeName}}.{{restHandlerField}} = new RestHandler(RestName()); - public void {{rootNodeName}}.{{restSetPortMethod}}(int port) { - {{restHandlerField}}.setPort(port); - } - public void {{rootNodeName}}.{{restCloseMethod}}() { - {{restHandlerField}}.close(); - } + private RestServerHandler {{rootNodeName}}.{{restHandlerField}} = new RestServerHandler(RestName()); {{#getRootTypeComponents}} - {{#first}}inh RestHandler ASTNode.{{restHandlerAttribute}}();{{/first}} + {{#first}}inh RestServerHandler ASTNode.{{restHandlerAttribute}}();{{/first}} eq {{rootNodeName}}.get{{name}}().{{restHandlerAttribute}}() = {{restHandlerField}}; {{/getRootTypeComponents}} {{^getRootTypeComponents}} - syn RestHandler {{rootNodeName}}.{{restHandlerAttribute}}() = {{restHandlerField}}; + syn RestServerHandler {{rootNodeName}}.{{restHandlerAttribute}}() = {{restHandlerField}}; {{/getRootTypeComponents}} } diff --git a/src/main/resources/sendDefinition.mustache b/src/main/resources/sendDefinition.mustache new file mode 100644 index 0000000000000000000000000000000000000000..517baab18824ead12ebca5f1d22901b3a960b0ba --- /dev/null +++ b/src/main/resources/sendDefinition.mustache @@ -0,0 +1,51 @@ + 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(); + } diff --git a/src/main/resources/sendDefinitionPull.mustache b/src/main/resources/sendDefinitionPull.mustache deleted file mode 100644 index 598846d86f9fc67167de7896f42c30cd0cfc3360..0000000000000000000000000000000000000000 --- a/src/main/resources/sendDefinitionPull.mustache +++ /dev/null @@ -1,7 +0,0 @@ - public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) { - {{handlerAttribute}}().{{newConnectionMethod}}({{connectParameterName}}, () -> { - {{tokenResetMethod}}(); - {{> mappingApplication}} - return {{lastResult}}; - }); - } diff --git a/src/main/resources/sendDefinitionPush.mustache b/src/main/resources/sendDefinitionPush.mustache deleted file mode 100644 index 3f75b18274d687d306f7778f9846aeca592fa86f..0000000000000000000000000000000000000000 --- a/src/main/resources/sendDefinitionPush.mustache +++ /dev/null @@ -1,24 +0,0 @@ - private String {{parentTypeName}}.{{sendTopic}} = null; - private byte[] {{parentTypeName}}.{{lastValue}} = null; - - public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) { - {{sendTopic}} = {{connectParameterName}}; - {{updateMethod}}(); - if (writeCurrentValue) { - {{writeMethod}}(); - } - } - - protected boolean {{parentTypeName}}.{{updateMethod}}() { - {{tokenResetMethod}}(); - {{> mappingApplication}} - {{lastValue}} = {{lastResult}}; - return true; - } - - protected void {{parentTypeName}}.{{writeMethod}}() { - {{#loggingEnabledForWrites}} - System.out.println("[Send] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{sendTopic}}); - {{/loggingEnabledForWrites}} - {{handlerAttribute}}().publish({{sendTopic}}, {{lastValue}}); - } diff --git a/src/main/resources/tokenComponent.mustache b/src/main/resources/tokenComponent.mustache index 729f442aebfc67ee2bbf5e559a9946405a275260..7de943a37edd9358fec19e53575629a44e976cff 100644 --- a/src/main/resources/tokenComponent.mustache +++ b/src/main/resources/tokenComponent.mustache @@ -3,11 +3,11 @@ {{#DependencyDefinitions}} for ({{targetParentTypeName}} target : get{{internalRelationPrefix}}TargetList()) { {{#targetEndpointDefinition}} - {{#isPush}} + {{!#isPush}} if (target.{{updateMethod}}()) { target.{{writeMethod}}(); } - {{/isPush}} + {{!/isPush}} {{/targetEndpointDefinition}} } {{/DependencyDefinitions}}