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

working on concise grammar

- auto-format aspects
- some refactorings for #39
- unified handler setup
- cleanup
- update extending.md for new process (fewer steps now)
parent 8dd7a3fa
No related branches found
No related tags found
2 merge requests!22Resolve "Feature: Add context-free connect",!21Resolve "Make grammar(s) more concise"
Pipeline #12018 passed
This commit is part of merge request !21. Comments created here will be created in the context of that merge request.
Showing
with 388 additions and 363 deletions
# Extending `RagConnect` # Extending `RagConnect`
To add a new communication protocol, the following locations have to be changed (replace `ABC` and `abc` with the name of the protocol): To add a new communication protocol, the following locations have to be changed (replace `ABC` and `abc` with the name of the protocol).
Within `ragconnect.base/src/main/resources`: ### Within `ragconnect.base/src/main/resources`
{% raw %} {% raw %}
- Add a new handler `ABCHandler`, if appropriate, similar to the existing handlers - Add a new handler `ABCHandler.jadd`, similar to the existing handlers.
- If further methods are needed for handler initialization, add a new template `abc.mustache` containing those procedures. Add `{{#usesABC}}{{> abc}}{{/usesABC}}` at the top of `ragconnect.mustache` to use this template - In `handler.mustache`, add further methods if needed for handler usage in the application code (similar to `{{rootNodeName}}.{{SetupWaitUntilReadyMethodName}}` for `mqtt`)
- In `receiveDefinition.mustache` and `sendDefinition.mustache`: add a new case in the switch statement defining the logic to happen for both definitions. If the new protocol is close to a PUSH semantic, follow `mqtt`. If it is closer to PULL semantic, follow `rest`. - In `receiveDefinition.mustache` and `sendDefinition.mustache`: add a new case in the switch statements defining the logic to happen upon connect and disconnect for both definitions. If the new protocol is close to a PUSH semantic, follow `mqtt`. If it is closer to PULL semantic, follow `rest`.
{% endraw %} {% endraw %}
Within `ragconnect.base/src/main/jastadd`: ### Within `ragconnect.base/src/main/jastadd`
- In `backend/Configuration`: In `Handlers.jrag`: Add a new attribute `RagConnect.abcHandler()` returning the resolved handler
- Add a new static boolean flag `usesABC` to indicate whether the protocol is used
- In `backend/Generation`:
- Add new attributes for type `MRagConnect` for handler attribute and handler field, if needed
- Add attributes for newly introduced references in changed mustache templates, if any
- Add a newly constructed handler within the definition of `RagConnect.toMustache` with the needed fields (class name, construction snippet, handler attribute, handler field, the boolean flag you just added to Configuration)
- In `backend/MustacheNodesToYAML`:
- Add key-value-pair for `usesABC` (and handler, if any)
- Add key-value-pairs for newly introduced referemces in changed mustache templates, if any
In `ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java`: ### Within `ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler`
In `Compiler.java`:
- Add a new choice for `--protocols` similar to the existing ones - Add a new choice for `--protocols` similar to the existing ones
- Set the flag `usesABC` if the choice is given. - Add a newly constructed handler in `setConfiguration` with the needed fields (definition file name within `resources` directory, commonly `ABCHandler.jadd`; class name of the handler; unique name for the protocol; whether the handler is used, i.e., if it was given in `--protocols`)
- Add code to add the handler to the list `handlers` if the choice is given, i.e., if `ASTNode.usesABC`
Furthermore, new test cases are appreciated, see [below](#writing-tests). Furthermore, new test cases are appreciated, see [below](#writing-tests).
...@@ -58,7 +50,7 @@ All tests are required to run both locally, and within the CI. ...@@ -58,7 +50,7 @@ All tests are required to run both locally, and within the CI.
### build.gradle ### build.gradle
Use the [PreprocessorPlugin][preprocessor-plugin], the build process can be written concisely in three parts per task: Using the [PreprocessorPlugin][preprocessor-plugin], the build process can be written concisely in three parts per task:
```groovy ```groovy
task compileTreeAllowedTokens(type: RagConnectTest) { task compileTreeAllowedTokens(type: RagConnectTest) {
......
aspect Analysis { aspect Analysis {
// --- lookupTokenEndpointDefinition ---
inh java.util.List<EndpointDefinition> EndpointDefinition.lookupTokenEndpointDefinitions(TokenComponent token);
inh java.util.List<EndpointDefinition> EndpointTarget.lookupTokenEndpointDefinitions(TokenComponent token);
eq RagConnect.getConnectSpecificationFile().lookupTokenEndpointDefinitions(TokenComponent token) = lookupTokenEndpointDefinitions(token);
syn java.util.List<EndpointDefinition> RagConnect.lookupTokenEndpointDefinitions(TokenComponent token) {
java.util.List<EndpointDefinition> result = new java.util.ArrayList<>();
for (EndpointTarget target : allEndpointTargetList()) {
if (target.isTokenEndpointTarget() && target.asTokenEndpointTarget().getToken().equals(token)) {
result.add(target.containingEndpointDefinition());
}
}
return result;
}
// --- lookupTypeEndpointDefinition ---
inh java.util.List<EndpointDefinition> EndpointDefinition.lookupTypeEndpointDefinitions(TypeComponent type);
inh java.util.List<EndpointDefinition> EndpointTarget.lookupTypeEndpointDefinitions(TypeComponent type);
eq RagConnect.getConnectSpecificationFile().lookupTypeEndpointDefinitions(TypeComponent type) = lookupTypeEndpointDefinitions(type);
syn java.util.List<EndpointDefinition> RagConnect.lookupTypeEndpointDefinitions(TypeComponent type) {
java.util.List<EndpointDefinition> result = new java.util.ArrayList<>();
for (EndpointTarget target : allEndpointTargetList()) {
if (target.isTypeEndpointTarget() && target.asTypeEndpointTarget().getType().equals(type)) {
result.add(target.containingEndpointDefinition());
}
}
return result;
}
// --- lookupDependencyDefinition ---
inh DependencyDefinition DependencyDefinition.lookupDependencyDefinition(TypeDecl source, String id);
eq RagConnect.getConnectSpecificationFile().lookupDependencyDefinition(TypeDecl source, String id) {
for (DependencyDefinition def : allDependencyDefinitionList()) {
if (def.getID().equals(id) && def.getSource().containingTypeDecl().equals(source)) {
return def;
}
}
return null;
}
// --- isAlreadyDefined --- // --- isAlreadyDefined ---
syn boolean EndpointDefinition.isAlreadyDefined() = getEndpointTarget().isAlreadyDefined(); syn boolean EndpointDefinition.isAlreadyDefined() = getEndpointTarget().isAlreadyDefined();
syn boolean EndpointTarget.isAlreadyDefined(); syn boolean EndpointTarget.isAlreadyDefined();
...@@ -60,7 +21,9 @@ aspect Analysis { ...@@ -60,7 +21,9 @@ aspect Analysis {
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);
eq JavaArrayMappingDefinitionType.assignableTo(JavaTypeUse target) { eq JavaArrayMappingDefinitionType.assignableTo(JavaTypeUse target) {
if (!target.getName().endsWith("[]")) { return false; } if (!target.getName().endsWith("[]")) {
return false;
}
return getType().assignableTo(new SimpleJavaTypeUse(target.getName().replace("[]", ""))); return getType().assignableTo(new SimpleJavaTypeUse(target.getName().replace("[]", "")));
} }
syn boolean JavaTypeUse.assignableTo(JavaTypeUse target) { syn boolean JavaTypeUse.assignableTo(JavaTypeUse target) {
...@@ -70,20 +33,28 @@ aspect Analysis { ...@@ -70,20 +33,28 @@ aspect Analysis {
syn String JavaTypeUse.primitivePrettyPrint() { syn String JavaTypeUse.primitivePrettyPrint() {
switch (getName()) { switch (getName()) {
case "boolean": case "boolean":
case "Boolean": return "boolean"; case "Boolean":
return "boolean";
case "int": case "int":
case "Integer": return "int"; case "Integer":
return "int";
case "short": case "short":
case "Short": return "short"; case "Short":
return "short";
case "long": case "long":
case "Long": return "long"; case "Long":
return "long";
case "float": case "float":
case "Float": return "float"; case "Float":
return "float";
case "double": case "double":
case "Double": return "double"; case "Double":
return "double";
case "char": case "char":
case "Character": return "char"; case "Character":
default: return getName(); return "char";
default:
return getName();
} }
} }
......
aspect Configuration { aspect ConfigurationShortcuts {
public static boolean ASTNode.loggingEnabledForReads = false; syn boolean RagConnect.loggingEnabledForReads() = getConfiguration().getLoggingEnabledForReads();
public static boolean ASTNode.loggingEnabledForWrites = false; syn boolean RagConnect.loggingEnabledForWrites() = getConfiguration().getLoggingEnabledForWrites();
public static boolean ASTNode.loggingEnabledForIncremental = false; syn boolean RagConnect.loggingEnabledForIncremental() = getConfiguration().getLoggingEnabledForIncremental();
public static TypeDecl ASTNode.rootNode; syn TypeDecl RagConnect.rootNode() = getConfiguration().getRootNode();
public static String ASTNode.JastAddList = "List"; syn String RagConnect.JastAddList() = getConfiguration().getJastAddList();
public static boolean ASTNode.usesMqtt; syn boolean RagConnect.incrementalOptionActive() = getConfiguration().getIncrementalOptionActive();
public static boolean ASTNode.usesRest; syn boolean RagConnect.experimentalJastAdd329() = getConfiguration().getExperimentalJastAdd329();
public static boolean ASTNode.incrementalOptionActive;
public static boolean ASTNode.experimentalJastAdd329;
} }
...@@ -19,8 +19,9 @@ aspect Errors { ...@@ -19,8 +19,9 @@ aspect Errors {
when !getSend() && getEndpointTarget().isTokenEndpointTarget() && effectiveMappings().get(0) == null when !getSend() && getEndpointTarget().isTokenEndpointTarget() && effectiveMappings().get(0) == null
to RagConnect.errors(); to RagConnect.errors();
// TODO copy for type endpoint target EndpointDefinition contributes error("to-type of last mapping (" +
EndpointDefinition contributes error("to-type of last mapping (" + effectiveMappings().get(effectiveMappings().size() - 1).getToType().prettyPrint() + ") not assignable to type of the token (" + token().effectiveJavaTypeUse().prettyPrint() + ")!") effectiveMappings().get(effectiveMappings().size() - 1).getToType().prettyPrint() +
") not assignable to type of the token (" + token().effectiveJavaTypeUse().prettyPrint() + ")!")
when !getSend() && getEndpointTarget().isTokenEndpointTarget() && when !getSend() && getEndpointTarget().isTokenEndpointTarget() &&
!effectiveMappings().get(effectiveMappings().size() - 1).getToType().assignableTo( !effectiveMappings().get(effectiveMappings().size() - 1).getToType().assignableTo(
token().effectiveJavaTypeUse()) token().effectiveJavaTypeUse())
...@@ -65,12 +66,15 @@ aspect ErrorMessage { ...@@ -65,12 +66,15 @@ aspect ErrorMessage {
public ASTNode getNode() { public ASTNode getNode() {
return node; return node;
} }
public int getLine() { public int getLine() {
return line; return line;
} }
public int getCol() { public int getCol() {
return col; return col;
} }
public String getMessage() { public String getMessage() {
return message; return message;
} }
......
aspect RagConnectHandlers {
syn Handler RagConnect.mqttHandler() = resolveHandlerByName("mqtt");
syn Handler RagConnect.restHandler() = resolveHandlerByName("rest");
private Handler RagConnect.resolveHandlerByName(String uniqueName) {
for (Handler handler : getHandlerList()) {
if (uniqueName.equals(handler.getUniqueName())) {
return handler;
}
}
System.err.println("Could not find handler with name '" + uniqueName + "'");
return null;
}
}
aspect RagConnectNameResolution { aspect RagConnectNameResolution {
// --- lookupTokenEndpointDefinition ---
inh java.util.List<EndpointDefinition> EndpointDefinition.lookupTokenEndpointDefinitions(TokenComponent token);
inh java.util.List<EndpointDefinition> EndpointTarget.lookupTokenEndpointDefinitions(TokenComponent token);
eq RagConnect.getConnectSpecificationFile().lookupTokenEndpointDefinitions(TokenComponent token) = lookupTokenEndpointDefinitions(token);
syn java.util.List<EndpointDefinition> RagConnect.lookupTokenEndpointDefinitions(TokenComponent token) {
java.util.List<EndpointDefinition> result = new java.util.ArrayList<>();
for (EndpointTarget target : allEndpointTargetList()) {
if (target.isTokenEndpointTarget() && target.asTokenEndpointTarget().getToken().equals(token)) {
result.add(target.containingEndpointDefinition());
}
}
return result;
}
// --- lookupTypeEndpointDefinition ---
inh java.util.List<EndpointDefinition> EndpointDefinition.lookupTypeEndpointDefinitions(TypeComponent type);
inh java.util.List<EndpointDefinition> EndpointTarget.lookupTypeEndpointDefinitions(TypeComponent type);
eq RagConnect.getConnectSpecificationFile().lookupTypeEndpointDefinitions(TypeComponent type) = lookupTypeEndpointDefinitions(type);
syn java.util.List<EndpointDefinition> RagConnect.lookupTypeEndpointDefinitions(TypeComponent type) {
java.util.List<EndpointDefinition> result = new java.util.ArrayList<>();
for (EndpointTarget target : allEndpointTargetList()) {
if (target.isTypeEndpointTarget() && target.asTypeEndpointTarget().getType().equals(type)) {
result.add(target.containingEndpointDefinition());
}
}
return result;
}
// --- lookupDependencyDefinition ---
inh DependencyDefinition DependencyDefinition.lookupDependencyDefinition(TypeDecl source, String id);
eq RagConnect.getConnectSpecificationFile().lookupDependencyDefinition(TypeDecl source, String id) {
for (DependencyDefinition def : allDependencyDefinitionList()) {
if (def.getID().equals(id) && def.getSource().containingTypeDecl().equals(source)) {
return def;
}
}
return null;
}
// rel EndpointDefinition.Mapping* -> MappingDefinition // rel EndpointDefinition.Mapping* -> MappingDefinition
refine RefResolverStubs eq EndpointDefinition.resolveMappingByToken(String id, int position) { refine RefResolverStubs eq EndpointDefinition.resolveMappingByToken(String id, int position) {
...@@ -64,7 +102,7 @@ aspect RagConnectNameResolution { ...@@ -64,7 +102,7 @@ aspect RagConnectNameResolution {
} }
// rel ___ -> TokenComponent (from relast-preprocessor) // rel ___ -> TokenComponent (from relast-preprocessor)
// refine here to have an attribute without writing on stderr if not found // refine from relast PP here to have an attribute that does not write on stderr if no TokenComponent was found
refine NameResolution eq ASTNode.globallyResolveTokenComponentByToken(String id) { refine NameResolution eq ASTNode.globallyResolveTokenComponentByToken(String id) {
TokenComponent result = tryGloballyResolveTokenComponentByToken(id); TokenComponent result = tryGloballyResolveTokenComponentByToken(id);
if (result == null) { if (result == null) {
......
...@@ -112,7 +112,9 @@ aspect RagConnectNavigation { ...@@ -112,7 +112,9 @@ aspect RagConnectNavigation {
syn EndpointDefinition DependencyDefinition.targetEndpointDefinition() { syn EndpointDefinition DependencyDefinition.targetEndpointDefinition() {
// resolve definition in here, as we do not need resolveMethod in any other place (yet) // resolve definition in here, as we do not need resolveMethod in any other place (yet)
for (EndpointDefinition endpointDefinition : ragconnect().allEndpointDefinitionList()) { for (EndpointDefinition endpointDefinition : ragconnect().allEndpointDefinitionList()) {
if (!endpointDefinition.getSend()) { continue; } if (!endpointDefinition.getSend()) {
continue;
}
EndpointTarget endpointTarget = endpointDefinition.getEndpointTarget(); EndpointTarget endpointTarget = endpointDefinition.getEndpointTarget();
if (endpointTarget.isTokenEndpointTarget() && if (endpointTarget.isTokenEndpointTarget() &&
endpointTarget.asTokenEndpointTarget().getToken().equals(this.getTarget())) { endpointTarget.asTokenEndpointTarget().getToken().equals(this.getTarget())) {
......
RagConnect ::= ConnectSpecificationFile* Handler* Program ; RagConnect ::= ConnectSpecificationFile* Program Handler* Configuration;
abstract ConnectSpecification ::= EndpointDefinition* DependencyDefinition* MappingDefinition*; abstract ConnectSpecification ::= EndpointDefinition* DependencyDefinition* MappingDefinition*;
ConnectSpecificationFile : ConnectSpecification ::= <FileName>; ConnectSpecificationFile : ConnectSpecification ::= <FileName>;
...@@ -27,4 +27,13 @@ JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ; ...@@ -27,4 +27,13 @@ JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse; JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse;
DefaultMappingDefinition : MappingDefinition; DefaultMappingDefinition : MappingDefinition;
Handler ::= <ClassName> <Construction> <AttributeName> <FieldName> <InUse:boolean>; Handler ::= <DefinitionFileName> <ClassName> <UniqueName> <InUse:boolean>;
Configuration ::=
<LoggingEnabledForReads:boolean>
<LoggingEnabledForWrites:boolean>
<LoggingEnabledForIncremental:boolean>
<JastAddList:String>
<IncrementalOptionActive:boolean>
<ExperimentalJastAdd329:boolean>;
rel Configuration.RootNode -> TypeDecl ;
RagConnect ::= ConnectSpecificationFile* Program ;
abstract ConnectSpecification ::= EndpointDefinition* DependencyDefinition* MappingDefinition* ;
ConnectSpecificationFile : ConnectSpecification ::= <FileName> ;
abstract EndpointDefinition ::= <AlwaysApply:boolean> ;
rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*;
abstract TokenEndpointDefinition : EndpointDefinition;
rel TokenEndpointDefinition.Token <-> TokenComponent.TokenEndpointDefinition*;
ReceiveTokenEndpointDefinition : TokenEndpointDefinition;
SendTokenEndpointDefinition : TokenEndpointDefinition;
abstract TypeEndpointDefinition : EndpointDefinition ::= <IndexBasedListAccess:boolean> ;
rel TypeEndpointDefinition.Type <-> TypeComponent.TypeEndpointDefinition*;
ReceiveTypeEndpointDefinition : TypeEndpointDefinition ::= <WithAdd:boolean>;
SendTypeEndpointDefinition : TypeEndpointDefinition;
DependencyDefinition ::= <ID>;
rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
rel DependencyDefinition.Target -> Component;
MappingDefinition ::= <ID> FromType:MappingDefinitionType <FromVariableName> ToType:MappingDefinitionType <Content> ;
abstract MappingDefinitionType ::= ;
JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
DefaultMappingDefinition : MappingDefinition ;
// only used by parser
abstract UntypedEndpointDefinition : EndpointDefinition ::= <TokenOrType> <Indexed:boolean> <WithAdd:boolean> ;
ReceiveUntypedEndpointDefinition : UntypedEndpointDefinition;
SendUntypedEndpointDefinition : UntypedEndpointDefinition;
...@@ -6,7 +6,7 @@ Design considerations ...@@ -6,7 +6,7 @@ Design considerations
aspect AttributesForMustache { aspect AttributesForMustache {
syn List<TypeComponent> RagConnect.rootTypeComponents() { syn List<TypeComponent> RagConnect.rootTypeComponents() {
List<TypeComponent> result = new ArrayList<>(); List<TypeComponent> result = new ArrayList<>();
for (Component child : rootNode.getComponentList()) { for (Component child : rootNode().getComponentList()) {
if (child.isTypeComponent()) { if (child.isTypeComponent()) {
result.add(child.asTypeComponent()); result.add(child.asTypeComponent());
} }
...@@ -16,12 +16,11 @@ aspect AttributesForMustache { ...@@ -16,12 +16,11 @@ aspect AttributesForMustache {
syn boolean RagConnect.hasRootTypeComponents() = !rootTypeComponents().isEmpty(); syn boolean RagConnect.hasRootTypeComponents() = !rootTypeComponents().isEmpty();
syn String RagConnect.closeMethodName() = "ragconnectCloseConnections"; syn String RagConnect.closeMethodName() = "ragconnectCloseConnections";
syn String RagConnect.mqttHandlerAttribute() = "_mqttHandler";
syn String RagConnect.mqttHandlerField() = "_mqttHandler";
syn String RagConnect.mqttSetupWaitUntilReadyMethodName() = "ragconnectSetupMqttWaitUntilReady";
syn String RagConnect.restHandlerAttribute() = "_restHandler"; syn String Handler.AttributeName() = "_" + getUniqueName() + "Handler";
syn String RagConnect.restHandlerField() = "_restHandler"; syn String Handler.FieldName() = "_" + getUniqueName() + "Handler";
syn String Handler.SetupWaitUntilReadyMethodName() = "ragconnectSetup" + capitalize(getUniqueName()) + "WaitUntilReady";
syn String Handler.ConstructionSnippet() = "new " + getClassName() + "(\"Handler for " + ragconnect().rootNodeName() + ".\" + this.hashCode())";
syn boolean RagConnect.hasTreeListEndpoints() { syn boolean RagConnect.hasTreeListEndpoints() {
for (EndpointDefinition endpointDef : allEndpointDefinitionList()) { for (EndpointDefinition endpointDef : allEndpointDefinitionList()) {
...@@ -249,7 +248,7 @@ aspect AttributesForMustache { ...@@ -249,7 +248,7 @@ aspect AttributesForMustache {
aspect AspectGeneration { aspect AspectGeneration {
// --- rootNodeName --- // --- rootNodeName ---
syn String ASTNode.rootNodeName() = rootNode.getName(); syn String RagConnect.rootNodeName() = getConfiguration().getRootNode().getName();
} }
aspect GrammarGeneration { aspect GrammarGeneration {
......
...@@ -68,18 +68,18 @@ aspect DefaultMappings { ...@@ -68,18 +68,18 @@ aspect DefaultMappings {
} }
syn nta DefaultMappingDefinition RagConnect.defaultBytesToListTreeMapping(String typeName) { syn nta DefaultMappingDefinition RagConnect.defaultBytesToListTreeMapping(String typeName) {
return treeDefaultMappingDefinition("byte[]", JastAddList + "<" + typeName + ">", return treeDefaultMappingDefinition("byte[]", JastAddList() + "<" + typeName + ">",
"String content = new String(input);\n" + "String content = new String(input);\n" +
"com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();\n" + "com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();\n" +
"com.fasterxml.jackson.core.JsonFactory factory = new com.fasterxml.jackson.core.JsonFactory();\n" + "com.fasterxml.jackson.core.JsonFactory factory = new com.fasterxml.jackson.core.JsonFactory();\n" +
"com.fasterxml.jackson.core.JsonParser parser = factory.createParser(content);\n" + "com.fasterxml.jackson.core.JsonParser parser = factory.createParser(content);\n" +
JastAddList + "<" + typeName + ">" + " result = " + typeName + ".deserializeList((com.fasterxml.jackson.databind.node.ArrayNode)mapper.readTree(parser));\n" + JastAddList() + "<" + typeName + ">" + " result = " + typeName + ".deserializeList((com.fasterxml.jackson.databind.node.ArrayNode)mapper.readTree(parser));\n" +
"parser.close();\n" + "parser.close();\n" +
"return result;" "return result;"
); );
} }
syn nta DefaultMappingDefinition RagConnect.defaultListTreeToBytesMapping() { syn nta DefaultMappingDefinition RagConnect.defaultListTreeToBytesMapping() {
return treeDefaultMappingDefinition(JastAddList, "byte[]", return treeDefaultMappingDefinition(JastAddList(), "byte[]",
"java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();\n" + "java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();\n" +
"com.fasterxml.jackson.core.JsonFactory factory = new com.fasterxml.jackson.core.JsonFactory();\n" + "com.fasterxml.jackson.core.JsonFactory factory = new com.fasterxml.jackson.core.JsonFactory();\n" +
"com.fasterxml.jackson.core.JsonGenerator generator = factory.createGenerator(outputStream, com.fasterxml.jackson.core.JsonEncoding.UTF8);\n" + "com.fasterxml.jackson.core.JsonGenerator generator = factory.createGenerator(outputStream, com.fasterxml.jackson.core.JsonEncoding.UTF8);\n" +
...@@ -176,8 +176,10 @@ aspect Mappings { ...@@ -176,8 +176,10 @@ aspect Mappings {
case "float": case "float":
case "double": case "double":
case "char": case "char":
case "byte": return true; case "byte":
default: return false; return true;
default:
return false;
} }
} }
syn boolean MappingDefinitionType.isPrimitiveType() = false; syn boolean MappingDefinitionType.isPrimitiveType() = false;
...@@ -193,30 +195,40 @@ aspect Mappings { ...@@ -193,30 +195,40 @@ aspect Mappings {
try { try {
TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName()); TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName());
return typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultBytesToListTreeMapping(typeDecl.getName()) : ragconnect().defaultBytesToTreeMapping(typeDecl.getName()); return typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultBytesToListTreeMapping(typeDecl.getName()) : ragconnect().defaultBytesToTreeMapping(typeDecl.getName());
} catch (Exception ignore) {} } catch (Exception ignore) {
}
} }
switch (targetTypeName()) { switch (targetTypeName()) {
case "boolean": case "boolean":
case "Boolean": return ragconnect().defaultBytesToBooleanMapping(); case "Boolean":
return ragconnect().defaultBytesToBooleanMapping();
case "int": case "int":
case "Integer": return ragconnect().defaultBytesToIntMapping(); case "Integer":
return ragconnect().defaultBytesToIntMapping();
case "short": case "short":
case "Short": return ragconnect().defaultBytesToShortMapping(); case "Short":
return ragconnect().defaultBytesToShortMapping();
case "long": case "long":
case "Long": return ragconnect().defaultBytesToLongMapping(); case "Long":
return ragconnect().defaultBytesToLongMapping();
case "float": case "float":
case "Float": return ragconnect().defaultBytesToFloatMapping(); case "Float":
return ragconnect().defaultBytesToFloatMapping();
case "double": case "double":
case "Double": return ragconnect().defaultBytesToDoubleMapping(); case "Double":
return ragconnect().defaultBytesToDoubleMapping();
case "char": case "char":
case "Character": return ragconnect().defaultBytesToCharMapping(); case "Character":
case "String": return ragconnect().defaultBytesToStringMapping(); return ragconnect().defaultBytesToCharMapping();
case "String":
return ragconnect().defaultBytesToStringMapping();
default: default:
try { try {
TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName()); TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName());
// TODO: also support list-types, if list is first type // TODO: also support list-types, if list is first type
return ragconnect().defaultBytesToTreeMapping(typeDecl.getName()); return ragconnect().defaultBytesToTreeMapping(typeDecl.getName());
} catch (Exception ignore) {} } catch (Exception ignore) {
}
System.err.println("Could not find suitable default mapping for " + targetTypeName() + " on " + this); System.err.println("Could not find suitable default mapping for " + targetTypeName() + " on " + this);
return null; return null;
} }
...@@ -228,30 +240,40 @@ aspect Mappings { ...@@ -228,30 +240,40 @@ aspect Mappings {
try { try {
TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName()); TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName());
return typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultListTreeToBytesMapping() : ragconnect().defaultTreeToBytesMapping(typeDecl.getName()); return typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultListTreeToBytesMapping() : ragconnect().defaultTreeToBytesMapping(typeDecl.getName());
} catch (Exception ignore) {} } catch (Exception ignore) {
}
} }
switch (targetTypeName()) { switch (targetTypeName()) {
case "boolean": case "boolean":
case "Boolean": return ragconnect().defaultBooleanToBytesMapping(); case "Boolean":
return ragconnect().defaultBooleanToBytesMapping();
case "int": case "int":
case "Integer": return ragconnect().defaultIntToBytesMapping(); case "Integer":
return ragconnect().defaultIntToBytesMapping();
case "short": case "short":
case "Short": return ragconnect().defaultShortToBytesMapping(); case "Short":
return ragconnect().defaultShortToBytesMapping();
case "long": case "long":
case "Long": return ragconnect().defaultLongToBytesMapping(); case "Long":
return ragconnect().defaultLongToBytesMapping();
case "float": case "float":
case "Float": return ragconnect().defaultFloatToBytesMapping(); case "Float":
return ragconnect().defaultFloatToBytesMapping();
case "double": case "double":
case "Double": return ragconnect().defaultDoubleToBytesMapping(); case "Double":
return ragconnect().defaultDoubleToBytesMapping();
case "char": case "char":
case "Character": return ragconnect().defaultCharToBytesMapping(); case "Character":
case "String": return ragconnect().defaultStringToBytesMapping(); return ragconnect().defaultCharToBytesMapping();
case "String":
return ragconnect().defaultStringToBytesMapping();
default: default:
try { try {
TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName()); TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName());
// TODO: also support list-types, if list is last type // TODO: also support list-types, if list is last type
return ragconnect().defaultTreeToBytesMapping(typeDecl.getName()); return ragconnect().defaultTreeToBytesMapping(typeDecl.getName());
} catch (Exception ignore) {} } catch (Exception ignore) {
}
System.err.println("Could not find suitable default mapping for " + targetTypeName() + " on " + this); System.err.println("Could not find suitable default mapping for " + targetTypeName() + " on " + this);
return null; return null;
} }
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
"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); }
//"tree" { return sym(Terminals.TREE); }
//"list" { return sym(Terminals.LIST); }
"with" { return sym(Terminals.WITH); } "with" { return sym(Terminals.WITH); }
"indexed" { return sym(Terminals.INDEXED); } "indexed" { return sym(Terminals.INDEXED); }
"add" { return sym(Terminals.ADD); } "add" { return sym(Terminals.ADD); }
...@@ -68,6 +68,7 @@ public class Compiler extends AbstractCompiler { ...@@ -68,6 +68,7 @@ public class Compiler extends AbstractCompiler {
} }
RagConnect ragConnect = parseProgram(getConfiguration().getFiles()); RagConnect ragConnect = parseProgram(getConfiguration().getFiles());
setConfiguration(ragConnect);
if (!ragConnect.errors().isEmpty()) { if (!ragConnect.errors().isEmpty()) {
StringBuilder sb = new StringBuilder("Errors:\n"); StringBuilder sb = new StringBuilder("Errors:\n");
...@@ -79,24 +80,17 @@ public class Compiler extends AbstractCompiler { ...@@ -79,24 +80,17 @@ public class Compiler extends AbstractCompiler {
} }
if (optionPrintYaml.value()) { if (optionPrintYaml.value()) {
System.err.println("Currently unsupported option!"); System.err.println("'--printYaml' currently unsupported option!");
// ASTNode.rootNode = ragConnect.getProgram().resolveTypeDecl(optionRootNode.value());
// String yamlContent = ragConnect.toMustache().toYAML().prettyPrint();
// System.out.println(yamlContent);
// writeToFile(getConfiguration().outputDir().toPath().resolve("RagConnect.yml"), yamlContent);
return 1; return 1;
} }
LOGGER.fine("Writing output files"); LOGGER.fine("Writing output files");
final List<String> handlers = new ArrayList<>();
if (ASTNode.usesMqtt) {
handlers.add("MqttHandler.jadd");
}
if (ASTNode.usesRest) {
handlers.add("RestHandler.jadd");
}
// copy handlers into outputDir // copy handlers into outputDir
for (String handlerFileName : handlers) { for (Handler handler : ragConnect.getHandlerList()) {
if (!handler.getInUse()) {
continue;
}
String handlerFileName = handler.getDefinitionFileName();
try { try {
InputStream inputStream = Compiler.class.getClassLoader().getResourceAsStream(handlerFileName); InputStream inputStream = Compiler.class.getClassLoader().getResourceAsStream(handlerFileName);
if (inputStream == null) { if (inputStream == null) {
...@@ -114,7 +108,7 @@ public class Compiler extends AbstractCompiler { ...@@ -114,7 +108,7 @@ public class Compiler extends AbstractCompiler {
writeToFile(outputFile, grammarFile.generateAbstractGrammar()); writeToFile(outputFile, grammarFile.generateAbstractGrammar());
} }
writeToFile(getConfiguration().outputDir().toPath().resolve("RagConnect.jadd"), writeToFile(getConfiguration().outputDir().toPath().resolve("RagConnect.jadd"),
generateAspect(ragConnect, optionRootNode.value())); generateAspect(ragConnect));
return 0; return 0;
} }
...@@ -130,14 +124,14 @@ public class Compiler extends AbstractCompiler { ...@@ -130,14 +124,14 @@ public class Compiler extends AbstractCompiler {
/** /**
* Reads the version string. * Reads the version string.
* * <p>
* The version string is read from the property file * The version string is read from the property file
* src/main/resources/Version.properties. This * src/main/resources/Version.properties. This
* file should be generated during the build process. If it is missing * file should be generated during the build process. If it is missing
* then there is some problem in the build script. * then there is some problem in the build script.
* *
* @author Jesper Öqvist <jesper.oqvist@cs.lth.se>
* @return the read version string, or <code>version ?</code> * @return the read version string, or <code>version ?</code>
* @author Jesper Öqvist <jesper.oqvist@cs.lth.se>
*/ */
private String readVersion() { private String readVersion() {
try { try {
...@@ -169,7 +163,7 @@ public class Compiler extends AbstractCompiler { ...@@ -169,7 +163,7 @@ public class Compiler extends AbstractCompiler {
.addAcceptedValue(OPTION_PROTOCOL_REST, "Enable REST") .addAcceptedValue(OPTION_PROTOCOL_REST, "Enable REST")
); );
optionPrintYaml = addOption( optionPrintYaml = addOption(
new BooleanOption("printYaml", "Print out YAML instead of generating files") new BooleanOption("printYaml", "Print out YAML instead of generating files (currently unsupported)")
.defaultValue(false)); .defaultValue(false));
optionVerbose = addOption( optionVerbose = addOption(
new BooleanOption("verbose", "Print more messages while compiling.") new BooleanOption("verbose", "Print more messages while compiling.")
...@@ -235,20 +229,7 @@ public class Compiler extends AbstractCompiler { ...@@ -235,20 +229,7 @@ public class Compiler extends AbstractCompiler {
ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration); ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration);
ragConnect.additionalTokens().forEach(TypeDecl::addComponent); ragConnect.additionalTokens().forEach(TypeDecl::addComponent);
ASTNode.loggingEnabledForReads = optionLogReads.value();
ASTNode.loggingEnabledForWrites = optionLogWrites.value();
ASTNode.loggingEnabledForIncremental = optionLogIncremental.value();
ASTNode.experimentalJastAdd329 = optionExperimentalJastAdd329.value();
// reuse "--incremental" option of JastAdd
ASTNode.incrementalOptionActive = getConfiguration().incremental() && getConfiguration().traceFlush();
LOGGER.fine(() -> "ASTNode.incrementalOptionActive = " + ASTNode.incrementalOptionActive);
// reuse "--List" option of JastAdd
ASTNode.JastAddList = getConfiguration().listType();
ASTNode.usesMqtt = optionProtocols.hasValue(OPTION_PROTOCOL_MQTT);
ASTNode.usesRest = optionProtocols.hasValue(OPTION_PROTOCOL_REST);
return ragConnect; return ragConnect;
} }
...@@ -281,6 +262,7 @@ public class Compiler extends AbstractCompiler { ...@@ -281,6 +262,7 @@ public class Compiler extends AbstractCompiler {
/** /**
* Extracts the basename of the given file, with file extension * Extracts the basename of the given file, with file extension
*
* @param filename the given filename * @param filename the given filename
* @return the basename * @return the basename
*/ */
...@@ -288,20 +270,29 @@ public class Compiler extends AbstractCompiler { ...@@ -288,20 +270,29 @@ public class Compiler extends AbstractCompiler {
return new File(filename).getName(); return new File(filename).getName();
} }
// protected void printUsage() { private void setConfiguration(RagConnect ragConnect) {
// System.out.println("Usage: java -jar ragconnect.jar [--option1] [--option2=value] ... <filename1> <filename2> ... "); ragConnect.setConfiguration(new Configuration());
// System.out.println("Options:"); ragConnect.getConfiguration().setLoggingEnabledForReads(optionLogReads.value());
// System.out.print(commandLine.printOptionHelp()); ragConnect.getConfiguration().setLoggingEnabledForWrites(optionLogWrites.value());
// } ragConnect.getConfiguration().setLoggingEnabledForIncremental(optionLogIncremental.value());
ragConnect.getConfiguration().setExperimentalJastAdd329(optionExperimentalJastAdd329.value());
// reuse "--incremental" and "--trace=flush" options of JastAdd
boolean incrementalOptionActive = this.getConfiguration().incremental() && this.getConfiguration().traceFlush();
ragConnect.getConfiguration().setIncrementalOptionActive(incrementalOptionActive);
LOGGER.fine(() -> "ragConnect.getConfiguration().IncrementalOptionActive = " + incrementalOptionActive);
// reuse "--List" option of JastAdd
ragConnect.getConfiguration().setJastAddList(this.getConfiguration().listType());
ragConnect.getConfiguration().setRootNode(ragConnect.getProgram().resolveTypeDecl(optionRootNode.value()));
// Handler ::= <ClassName> <UniqueName> <InUse:boolean>;
ragConnect.addHandler(new Handler("MqttHandler.jadd", "MqttServerHandler", "mqtt", optionProtocols.hasValue(OPTION_PROTOCOL_MQTT)));
ragConnect.addHandler(new Handler("RestHandler.jadd", "RestServerHandler", "rest", optionProtocols.hasValue(OPTION_PROTOCOL_REST)));
}
public String generateAspect(RagConnect ragConnectSpec, String rootNodeName) { public String generateAspect(RagConnect ragConnect) {
ASTNode.rootNode = ragConnectSpec.getProgram().resolveTypeDecl(rootNodeName);
// Handler ::= <ClassName> <Construction> <AttributeName> <FieldName> <InUse:boolean>;
ragConnectSpec.addHandler(new Handler("MqttServerHandler", "new MqttServerHandler(\"RagConnectMQTT\")",
ragConnectSpec.mqttHandlerAttribute(), ragConnectSpec.mqttHandlerField(), ASTNode.usesMqtt));
ragConnectSpec.addHandler(new Handler("RestServerHandler", "new RestServerHandler(\"RagConnectREST\")",
ragConnectSpec.restHandlerAttribute(), ragConnectSpec.restHandlerField(), ASTNode.usesRest));
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() { com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() {
@Override @Override
...@@ -321,7 +312,7 @@ public class Compiler extends AbstractCompiler { ...@@ -321,7 +312,7 @@ public class Compiler extends AbstractCompiler {
com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory(); com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
mf.setObjectHandler(roh); mf.setObjectHandler(roh);
com.github.mustachejava.Mustache m = mf.compile("ragconnect.mustache"); com.github.mustachejava.Mustache m = mf.compile("ragconnect.mustache");
m.execute(new java.io.PrintWriter(new org.jastadd.ragconnect.compiler.AppendableWriter(sb)), ragConnectSpec); m.execute(new java.io.PrintWriter(new org.jastadd.ragconnect.compiler.AppendableWriter(sb)), ragConnect);
return sb.toString(); return sb.toString();
} }
} }
...@@ -316,11 +316,8 @@ public class MqttHandler { ...@@ -316,11 +316,8 @@ public class MqttHandler {
needSubscribe = pairToAddTo.callbacks.isEmpty(); needSubscribe = pairToAddTo.callbacks.isEmpty();
pairToAddTo.callbacks.add(callback); pairToAddTo.callbacks.add(callback);
} else { // normal topic } else { // normal topic
java.util.List<java.util.function.BiConsumer<String, byte[]>> callbacksForTopic = normalCallbacks.get(topic); java.util.List<java.util.function.BiConsumer<String, byte[]>> callbacksForTopic = normalCallbacks.
if (callbacksForTopic == null) { computeIfAbsent(topic, t -> new java.util.ArrayList<>());
callbacksForTopic = new java.util.ArrayList<>();
normalCallbacks.put(topic, callbacksForTopic);
}
needSubscribe = callbacksForTopic.isEmpty(); needSubscribe = callbacksForTopic.isEmpty();
callbacksForTopic.add(callback); callbacksForTopic.add(callback);
} }
...@@ -346,7 +343,10 @@ public class MqttHandler { ...@@ -346,7 +343,10 @@ public class MqttHandler {
}); });
}); });
try { try {
operationFinished.await(2, java.util.concurrent.TimeUnit.SECONDS); boolean finishedInTime = operationFinished.await(2, java.util.concurrent.TimeUnit.SECONDS);
if (!finishedInTime) {
return false;
}
return success.get(); return success.get();
} catch (InterruptedException e) { } catch (InterruptedException e) {
return false; return false;
...@@ -428,7 +428,10 @@ public class MqttHandler { ...@@ -428,7 +428,10 @@ public class MqttHandler {
}); });
}); });
try { try {
operationFinished.await(2, java.util.concurrent.TimeUnit.SECONDS); boolean finishedInTime = operationFinished.await(2, java.util.concurrent.TimeUnit.SECONDS);
if (!finishedInTime) {
return false;
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
logger.catching(e); logger.catching(e);
success.set(false); success.set(false);
......
aspect RagConnectHandler { aspect RagConnectHandler {
{{#Handlers}} {{#Handlers}}
{{#InUse}} {{#InUse}}
private {{ClassName}} {{rootNodeName}}.{{FieldName}} = {{{Construction}}}; private {{ClassName}} {{rootNodeName}}.{{FieldName}} = {{{ConstructionSnippet}}};
{{#hasRootTypeComponents}}inh {{ClassName}} ASTNode.{{AttributeName}}();{{/hasRootTypeComponents}} {{#hasRootTypeComponents}}inh {{ClassName}} ASTNode.{{AttributeName}}();{{/hasRootTypeComponents}}
{{#rootTypeComponents}} {{#rootTypeComponents}}
eq {{rootNodeName}}.get{{name}}().{{AttributeName}}() = {{FieldName}}; eq {{rootNodeName}}.get{{name}}().{{AttributeName}}() = {{FieldName}};
...@@ -14,6 +14,15 @@ aspect RagConnectHandler { ...@@ -14,6 +14,15 @@ aspect RagConnectHandler {
{{#InUse}}{{FieldName}}.close();{{/InUse}} {{#InUse}}{{FieldName}}.close();{{/InUse}}
{{/Handlers}} {{/Handlers}}
} }
{{#mqttHandler}}
{{#InUse}}
public void {{rootNodeName}}.{{SetupWaitUntilReadyMethodName}}(long time, java.util.concurrent.TimeUnit unit) {
{{FieldName}}.setupWaitUntilReady(time, unit);
}
{{/InUse}}
{{/mqttHandler}}
class RagConnectToken { class RagConnectToken {
static java.util.concurrent.atomic.AtomicLong counter = new java.util.concurrent.atomic.AtomicLong(0); static java.util.concurrent.atomic.AtomicLong counter = new java.util.concurrent.atomic.AtomicLong(0);
final long id; final long id;
......
aspect MQTT {
public void {{rootNodeName}}.{{mqttSetupWaitUntilReadyMethodName}}(long time, java.util.concurrent.TimeUnit unit) {
{{mqttHandlerField}}.setupWaitUntilReady(time, unit);
}
}
{{#usesMqtt}}{{> mqtt}}{{/usesMqtt}}
{{> handler}} {{> handler}}
aspect RagConnect { aspect RagConnect {
{{#allEndpointDefinitionList}} {{#allEndpointDefinitionList}}
......
...@@ -92,19 +92,23 @@ private boolean {{parentTypeName}}.{{internalConnectMethodName}}(String {{connec ...@@ -92,19 +92,23 @@ private boolean {{parentTypeName}}.{{internalConnectMethodName}}(String {{connec
RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}"); RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}");
boolean success; boolean success;
switch (scheme) { switch (scheme) {
{{#usesMqtt}} {{#mqttHandler}}
{{#InUse}}
case "mqtt": case "mqtt":
success = {{mqttHandlerAttribute}}().newConnection(connectToken, consumer); success = {{AttributeName}}().newConnection(connectToken, consumer);
break; break;
{{/usesMqtt}} {{/InUse}}
{{#usesRest}} {{/mqttHandler}}
{{#restHandler}}
{{#InUse}}
case "rest": case "rest":
success = {{restHandlerAttribute}}().newPUTConnection(connectToken, input -> { success = {{AttributeName}}().newPUTConnection(connectToken, input -> {
// TODO wildcard-topic not supported yet // TODO wildcard-topic not supported yet
consumer.accept("", input.getBytes()); consumer.accept("", input.getBytes());
}); });
break; break;
{{/usesRest}} {{/InUse}}
{{/restHandler}}
default: default:
System.err.println("Unknown protocol '" + scheme + "'."); System.err.println("Unknown protocol '" + scheme + "'.");
success = false; success = false;
...@@ -124,14 +128,18 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam ...@@ -124,14 +128,18 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
} }
RagConnectDisconnectHandlerMethod disconnectingMethod; RagConnectDisconnectHandlerMethod disconnectingMethod;
switch (scheme) { switch (scheme) {
{{#usesMqtt}} {{#mqttHandler}}
case "mqtt": disconnectingMethod = {{mqttHandlerAttribute}}()::disconnect; {{#InUse}}
case "mqtt": disconnectingMethod = {{AttributeName}}()::disconnect;
break; break;
{{/usesMqtt}} {{/InUse}}
{{#usesRest}} {{/mqttHandler}}
case "rest": disconnectingMethod = {{restHandlerAttribute}}()::disconnect; {{#restHandler}}
{{#InUse}}
case "rest": disconnectingMethod = {{AttributeName}}()::disconnect;
break; break;
{{/usesRest}} {{/InUse}}
{{/restHandler}}
default: default:
System.err.println("Unknown protocol '" + scheme + "' in '" + {{connectParameterName}} + "' for disconnecting {{parentTypeName}}.{{entityName}}"); System.err.println("Unknown protocol '" + scheme + "' in '" + {{connectParameterName}} + "' for disconnecting {{parentTypeName}}.{{entityName}}");
return false; return false;
......
...@@ -5,10 +5,11 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete ...@@ -5,10 +5,11 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}"); RagConnectToken connectToken = new RagConnectToken(uri, "{{entityName}}");
boolean success; boolean success;
switch (scheme) { switch (scheme) {
{{#usesMqtt}} {{#mqttHandler}}
{{#InUse}}
case "mqtt": case "mqtt":
final MqttHandler handler = {{mqttHandlerAttribute}}().resolveHandler(uri); final MqttHandler handler = {{AttributeName}}().resolveHandler(uri);
final String topic = {{mqttHandlerAttribute}}().extractTopic(uri); final String topic = {{AttributeName}}().extractTopic(uri);
{{senderName}}.add(() -> { {{senderName}}.add(() -> {
{{#loggingEnabledForWrites}} {{#loggingEnabledForWrites}}
System.out.println("[Send] {{entityName}} = " + {{getterMethodName}}() + " -> " + {{connectParameterName}}); System.out.println("[Send] {{entityName}} = " + {{getterMethodName}}() + " -> " + {{connectParameterName}});
...@@ -21,15 +22,18 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete ...@@ -21,15 +22,18 @@ public boolean {{parentTypeName}}.{{connectMethodName}}(String {{connectParamete
} }
success = true; success = true;
break; break;
{{/usesMqtt}} {{/InUse}}
{{#usesRest}} {{/mqttHandler}}
{{#restHandler}}
{{#InUse}}
case "rest": case "rest":
success = {{restHandlerAttribute}}().newGETConnection(connectToken, () -> { success = {{AttributeName}}().newGETConnection(connectToken, () -> {
{{updateMethodName}}(); {{updateMethodName}}();
return new String({{lastValue}}); return new String({{lastValue}});
}); });
break; break;
{{/usesRest}} {{/InUse}}
{{/restHandler}}
default: default:
System.err.println("Unknown protocol '" + scheme + "'."); System.err.println("Unknown protocol '" + scheme + "'.");
success = false; success = false;
...@@ -59,16 +63,20 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam ...@@ -59,16 +63,20 @@ public boolean {{parentTypeName}}.{{disconnectMethodName}}(String {{connectParam
{{/incrementalOptionActive}} {{/incrementalOptionActive}}
RagConnectDisconnectHandlerMethod disconnectingMethod; RagConnectDisconnectHandlerMethod disconnectingMethod;
switch (scheme) { switch (scheme) {
{{#usesMqtt}} {{#mqttHandler}}
{{#InUse}}
case "mqtt": case "mqtt":
disconnectingMethod = {{senderName}}::remove; disconnectingMethod = {{senderName}}::remove;
break; break;
{{/usesMqtt}} {{/InUse}}
{{#usesRest}} {{/mqttHandler}}
{{#restHandler}}
{{#InUse}}
case "rest": case "rest":
disconnectingMethod = {{restHandlerAttribute}}()::disconnect; disconnectingMethod = {{AttributeName}}()::disconnect;
break; break;
{{/usesRest}} {{/InUse}}
{{/restHandler}}
default: default:
System.err.println("Unknown protocol '" + scheme + "' in '" + {{connectParameterName}} + "' for disconnecting {{parentTypeName}}.{{entityName}}"); System.err.println("Unknown protocol '" + scheme + "' in '" + {{connectParameterName}} + "' for disconnecting {{parentTypeName}}.{{entityName}}");
return false; return false;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment