Commit 4b51070e authored by Jannis Joachim Tölle's avatar Jannis Joachim Tölle
Browse files

mqtt symbols

parent ffd664b9
Pipeline #150134 passed with stage
in 2 minutes and 39 seconds
......@@ -24,6 +24,7 @@ import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instance
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc.unit.constant.EMAConstantValue;
import de.monticore.lang.embeddedmontiarc.helper.SymbolPrinter;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.MiddlewareSymbol;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.mqtt.MqttConnectionSymbol;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.ros.RosConnectionSymbol;
import de.monticore.lang.monticar.stream._symboltable.NamedStreamSymbol;
import de.monticore.lang.monticar.ts.MCTypeSymbol;
......@@ -292,4 +293,8 @@ public class EMAPortSymbol extends CommonSymbol implements EMAElementSymbol {
public boolean isRosPort(){
return getMiddlewareSymbol().isPresent() && getMiddlewareSymbol().get().isKindOf(RosConnectionSymbol.KIND);
}
public boolean isMqttPort() {
return getMiddlewareSymbol().isPresent() && getMiddlewareSymbol().get().isKindOf(MqttConnectionSymbol.KIND);
}
}
......@@ -26,6 +26,7 @@ import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.cncModel
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc.unit.constant.EMAConstantValue;
import de.monticore.lang.embeddedmontiarc.helper.SymbolPrinter;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.MiddlewareSymbol;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.mqtt.MqttConnectionSymbol;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.ros.RosConnectionSymbol;
import de.monticore.lang.monticar.stream._symboltable.NamedStreamSymbol;
import de.monticore.lang.monticar.ts.MCTypeSymbol;
......@@ -278,4 +279,8 @@ public class EMAPortInstanceSymbol extends EMAPortSymbol implements EMAElementIn
public boolean isRosPort(){
return getMiddlewareSymbol().isPresent() && getMiddlewareSymbol().get().isKindOf(RosConnectionSymbol.KIND);
}
public boolean isMqttPort() {
return getMiddlewareSymbol().isPresent() && getMiddlewareSymbol().get().isKindOf(MqttConnectionSymbol.KIND);
}
}
package de.monticore.lang.embeddedmontiarc.tagging.middleware.mqtt;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.MiddlewareSymbol;
import de.monticore.lang.tagging._symboltable.TagKind;
import java.util.Optional;
public class MqttConnectionSymbol extends MiddlewareSymbol {
public static final MqttConnectionKind KIND = MqttConnectionKind.INSTANCE;
public MqttConnectionSymbol() {
super(KIND, Optional.empty(), Optional.empty(), Optional.empty());
}
public MqttConnectionSymbol(String topicName, String topicType) {
this(KIND, topicName, topicType);
}
public MqttConnectionSymbol(MqttConnectionKind kind, String topicName, String topicType) {
super(kind, Optional.ofNullable(topicName), Optional.ofNullable(topicType), Optional.empty());
}
public MqttConnectionSymbol(String topicName, String topicType, String msgField) {
this(KIND, topicName, topicType, msgField);
}
protected MqttConnectionSymbol(MqttConnectionKind kind, String topicName, String topicType, String msgField) {
super(kind, Optional.ofNullable(topicName), Optional.ofNullable(topicType), Optional.ofNullable(msgField));
}
@Override
public String toString() {
return String.format("MqttConnection = (%s, %s), %s",
getTopicName(), getTopicType(), getMsgField());
}
public Optional<String> getTopicName() {
return getValue(0);
}
public void setTopicName(String topicName) {
this.values.set(0, Optional.ofNullable(topicName));
}
public Optional<String> getTopicType() {
return getValue(1);
}
public void setTopicType(String topicType) {
this.values.set(1, Optional.ofNullable(topicType));
}
public Optional<String> getMsgField() {
return getValue(2);
}
public void setMsgField(String msgField) {
this.values.set(2, Optional.ofNullable(msgField));
}
public static class MqttConnectionKind extends TagKind {
public static final MqttConnectionKind INSTANCE = new MqttConnectionKind();
protected MqttConnectionKind() {
}
}
}
package de.monticore.lang.embeddedmontiarc.tagging.middleware.mqtt;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.cncModel.EMAPortSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAPortInstanceSymbol;
import de.monticore.lang.tagging._ast.*;
import de.monticore.lang.tagging._symboltable.TagSymbolCreator;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.monticore.symboltable.Scope;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.Joiners;
import de.se_rwth.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class MqttSymbolCreator implements TagSymbolCreator {
/**
* regular expression pattern:
* topic = {({name}, {type}), \( msgField = {msgField} \)\?}
* to test the pattern just enter:
* \s*\{\s*topic\s*=\s*\(\s*([a-z|A-Z|~|/][0-9|a-z|A-Z|_|/]*)\s*,\s*([a-z|A-Z][0-9|a-z|A-Z|_|/]*)\s*\)\s*(s*,\s*msgField\s*=\s*([a-z|A-Z][a-z|A-Z|1-9|_|\.|::|\(|\)]*)\s*)?\s*\}\s*
* at http://www.regexplanet.com/advanced/java/index.html
*/
public static final Pattern pattern = Pattern.compile("\\s*\\{\\s*topic\\s*=\\s*\\(\\s*([a-z|A-Z|~|/][0-9|a-z|A-Z|_|/]*)\\s*,\\s*([a-z|A-Z][0-9|a-z|A-Z|_|/]*)\\s*\\)\\s*(s*,\\s*msgField\\s*=\\s*([a-z|A-Z][a-z|A-Z|1-9|_|\\.|::|\\(|\\)]*)\\s*)?\\s*\\}\\s*");
public static Scope getGlobalScope(final Scope scope) {
Scope s = scope;
while (s.getEnclosingScope().isPresent()) {
s = s.getEnclosingScope().get();
}
return s;
}
public void create(ASTTaggingUnit unit, TaggingResolver tagging) {
if (unit.getQualifiedNameList().stream()
.map(q -> q.toString())
.filter(n -> n.endsWith("MqttToEmamSchema"))
.count() == 0) {
return; // the tagging model is not conform to the traceability tagging schema
}
final String packageName = Joiners.DOT.join(unit.getPackageList());
final String rootCmp = // if-else does not work b/c of final (required by streams)
(unit.getTagBody().getTargetModelOpt().isPresent()) ?
Joiners.DOT.join(packageName, unit.getTagBody().getTargetModelOpt().get()
.getQualifiedNameString()) :
packageName;
for (ASTTag element : unit.getTagBody().getTagList()) {
List<ASTTagElement> tagElements = element.getTagElementList().stream()
.filter(t -> t.getName().equals("MqttConnection"))
.collect(Collectors.toList());
// after that point we can throw error messages
List<Symbol> ports = element.getScopeList().stream()
.filter(this::checkScope)
.map(s -> (ASTNameScope) s)
.map(s -> tagging.resolve(Joiners.DOT.join(rootCmp, // resolve down does not try to reload symbol
s.getQualifiedNameString()), EMAPortSymbol.KIND))
.filter(Optional::isPresent) // if the symbol is not present, does not mean that the symbol
.map(Optional::get) // is not available at all, maybe it will be loaded later
.collect(Collectors.toList());
List<Symbol> portInstances = element.getScopeList().stream()
.filter(this::checkScope)
.map(s -> (ASTNameScope) s)
.map(s -> tagging.resolve(Joiners.DOT.join(rootCmp, // resolve down does not try to reload symbol
s.getQualifiedNameString()), EMAPortInstanceSymbol.KIND))
.filter(Optional::isPresent) // if the symbol is not present, does not mean that the symbol
.map(Optional::get) // is not available at all, maybe it will be loaded later
.collect(Collectors.toList());
List<Symbol> taggedSymbols = new ArrayList<>(ports);
taggedSymbols.addAll(portInstances);
//Empty tags
tagElements.stream()
.filter(t -> !t.getTagValueOpt().isPresent())
.forEachOrdered(tag -> {
taggedSymbols.stream()
.forEachOrdered(s -> {
MqttConnectionSymbol tmpSymbol = new MqttConnectionSymbol();
tagging.addTag(s, tmpSymbol);
if (s.isKindOf(EMAPortSymbol.KIND)) {
EMAPortSymbol p = (EMAPortSymbol) s;
p.setMiddlewareSymbol(tmpSymbol);
} else if (s.isKindOf(EMAPortInstanceSymbol.KIND)) {
EMAPortInstanceSymbol p = (EMAPortInstanceSymbol) s;
p.setMiddlewareSymbol(tmpSymbol);
}
});
});
//Tags with TagValue
tagElements.stream()
.filter(t -> t.getTagValueOpt().isPresent())
.map(t -> matchRegexPattern(t.getTagValueOpt().get()))
.filter(r -> r != null)
.forEachOrdered(m ->
taggedSymbols.stream()
.forEachOrdered(s -> {
MqttConnectionSymbol tmpSymbol = new MqttConnectionSymbol(m.group(1), m.group(2), m.group(4));
tagging.addTag(s, tmpSymbol);
if (s.isKindOf(EMAPortSymbol.KIND)) {
EMAPortSymbol p = (EMAPortSymbol) s;
p.setMiddlewareSymbol(tmpSymbol);
} else if (s.isKindOf(EMAPortInstanceSymbol.KIND)) {
EMAPortInstanceSymbol p = (EMAPortInstanceSymbol) s;
p.setMiddlewareSymbol(tmpSymbol);
}
}));
}
}
protected Matcher matchRegexPattern(String regex) {
Matcher matcher = pattern.matcher(regex);
if (matcher.matches()) {
return matcher;
}
Log.error(String.format("'%s' does not match the specified regex pattern '%s'",
regex,
"{topic = ({name}, {type}), msgField = {msgField}}"));
return null;
}
protected boolean checkScope(ASTScope scope) {
if (scope.getScopeKind().equals("NameScope")) {
return true;
}
Log.error(String.format("Invalid scope kind: '%s'. MqttConnection expects as scope kind 'NameScope'.", scope.getScopeKind()));
return false;
}
}
package de.monticore.lang.embeddedmontiarc.tagging.middleware.mqtt;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.monticore.symboltable.resolving.CommonResolvingFilter;
public class MqttToEmanTagSchema {
protected static MqttToEmanTagSchema instance = null;
protected MqttToEmanTagSchema() {
}
protected static MqttToEmanTagSchema getInstance() {
if (instance == null) {
instance = new MqttToEmanTagSchema();
}
return instance;
}
public static void registerTagTypes(TaggingResolver tagging) {
getInstance().doRegisterTagTypes(tagging);
}
protected void doRegisterTagTypes(TaggingResolver tagging) {
tagging.addTagSymbolCreator(new MqttSymbolCreator());
tagging.addTagSymbolResolvingFilter(CommonResolvingFilter.create(MqttConnectionSymbol.KIND));
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment