diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 98296c70f5cbef287ac6e7c45c1414cc40eb7528..b981616c4981e4c033e07cc56d3c75fbfc63cf0d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,10 +1,22 @@
stages:
-- linux
+- project
+- adapter
-BranchJobLinux:
- stage: linux
+BranchJobProject:
+ stage: project
image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emam2someip
script:
- mvn clean install -s settings.xml
except:
- master
+
+BranchJobAdapter:
+ stage: adapter
+ image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emam2someip
+ script:
+ - cd someip_adapter
+ - cmake .
+ - make
+ except:
+ - master
+
diff --git a/pom.xml b/pom.xml
index e415b1f698e491e46e6147f3da19ebd6d15dca7a..00e4a61b9c374fb563b869bb0fcc519f11d81aaf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,7 +51,7 @@
embedded-montiarc
0.1.10-SNAPSHOT
-
+
de.se_rwth.commons
diff --git a/src/main/java/de/monticore/lang/monticar/generator/someip/GeneratorSomeIP.java b/src/main/java/de/monticore/lang/monticar/generator/someip/GeneratorSomeIP.java
new file mode 100755
index 0000000000000000000000000000000000000000..34611b2edebeca4959e84308da03ee16fb2e1a13
--- /dev/null
+++ b/src/main/java/de/monticore/lang/monticar/generator/someip/GeneratorSomeIP.java
@@ -0,0 +1,52 @@
+package de.monticore.lang.monticar.generator.someip;
+
+import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
+import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAPortInstanceSymbol;
+//import de.monticore.lang.embeddedmontiarc.tagging.middleware.someip.SomeIPConnectionSymbol;
+import de.monticore.lang.monticar.generator.someip.template.SomeIPAdapterModel;
+import de.monticore.lang.monticar.generator.someip.template.SomeIPTemplates;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class GeneratorSomeIP {
+
+ List generateSomeIPAdapter(EMAComponentInstanceSymbol component) {
+ List files = new ArrayList<>();
+
+ // Get info about the ports from the component
+ Collection ports = component.getPortInstanceList();
+
+ // Create and fill model
+ SomeIPAdapterModel model = new SomeIPAdapterModel(component.getFullName());
+
+ model.addPorts(ports);
+
+ //Generate files and write to project
+ String content = SomeIPTemplates.generateSomeIPAdapter(model);
+
+ File file = new File("./target/generated-sources/ports.txt");
+ files.add(file);
+
+ FileWriter fr = null;
+ try {
+ fr = new FileWriter(file);
+ fr.write(content);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ //Close resources
+ try {
+ fr.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return files;
+ }
+
+}
diff --git a/src/main/java/de/monticore/lang/monticar/generator/someip/template/SomeIPAdapterModel.java b/src/main/java/de/monticore/lang/monticar/generator/someip/template/SomeIPAdapterModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..09b72c34d16a4ad47cbaf90544217e12d4dba484
--- /dev/null
+++ b/src/main/java/de/monticore/lang/monticar/generator/someip/template/SomeIPAdapterModel.java
@@ -0,0 +1,49 @@
+package de.monticore.lang.monticar.generator.someip.template;
+
+import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAPortInstanceSymbol;
+import de.monticore.lang.embeddedmontiarc.tagging.middleware.MiddlewareSymbol;
+import de.monticore.lang.embeddedmontiarc.tagging.middleware.someip.SomeIPConnectionSymbol;
+import de.monticore.lang.embeddedmontiarc.tagging.middleware.someip.SomeIPConnectionSymbol.SomeIPConnectionKind;
+
+import java.util.*;
+
+// Used to fill .ftl files
+
+public class SomeIPAdapterModel {
+
+ private String compName;
+ private List ports = new ArrayList<>();
+
+ public SomeIPAdapterModel(String compName) {
+ this.compName = compName;
+ }
+
+ public String getCompName() {
+ return compName;
+ }
+
+ // Parse through component to find information about its ports
+ public void addPorts(Collection ports)
+ {
+ for (EMAPortInstanceSymbol port : ports)
+ {
+ String kind = port.isIncoming()?"incoming":"outgoing";
+ String symbolKind = "unknown symbol";
+ Optional symbol = port.getMiddlewareSymbol();
+ if(symbol.isPresent() && symbol.get().isKindOf(SomeIPConnectionKind.INSTANCE))
+ {
+ SomeIPConnectionSymbol sym = (SomeIPConnectionSymbol) symbol.get();
+ String topicName = sym.getTopicName().isPresent()?sym.getTopicName().get():"unknown";
+ symbolKind = "someip, topic: "+topicName;
+ }
+
+ this.ports.add(port.getName()+" : "+kind+" ("+symbolKind+")");
+ }
+ }
+
+ public List getPorts()
+ {
+ return this.ports;
+ }
+
+}
diff --git a/src/main/java/de/monticore/lang/monticar/generator/someip/template/SomeIPTemplates.java b/src/main/java/de/monticore/lang/monticar/generator/someip/template/SomeIPTemplates.java
new file mode 100755
index 0000000000000000000000000000000000000000..cfa8b9b8b5a4bdded845000bbd99277a9cb4c3d8
--- /dev/null
+++ b/src/main/java/de/monticore/lang/monticar/generator/someip/template/SomeIPTemplates.java
@@ -0,0 +1,53 @@
+package de.monticore.lang.monticar.generator.someip.template;
+
+import de.se_rwth.commons.logging.Log;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateExceptionHandler;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SomeIPTemplates {
+
+ private static final Template SOMEIP_PRETTYPRINT;
+
+ // Loading .ftl files
+ static {
+ Configuration conf = new Configuration(Configuration.VERSION_2_3_23);
+ conf.setDefaultEncoding("UTF-8");
+ conf.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER);
+ conf.setLogTemplateExceptions(false);
+ conf.setClassForTemplateLoading(SomeIPTemplates.class, "");
+ try {
+ SOMEIP_PRETTYPRINT = conf.getTemplate("PrettyPrint.ftl");
+ } catch (IOException e) {
+ String msg = "could not load template";
+ Log.error(msg, e);
+ throw new RuntimeException(msg, e);
+ }
+ }
+
+ public static String generateSomeIPAdapter(SomeIPAdapterModel model) {
+ HashMap data = new HashMap<>();
+ data.put("model", model);
+ return generate(SOMEIP_PrettyPrint, data);
+ }
+
+
+ @SuppressWarnings("rawtypes")
+ private static String generate(Template template, Map dataForTemplate) {
+ Log.errorIfNull(template);
+ Log.errorIfNull(dataForTemplate);
+ StringWriter sw = new StringWriter();
+ try {
+ template.process(dataForTemplate, sw);
+ } catch (TemplateException | IOException e) {
+ Log.error("template generation failed, template: " + template.getName(), e);
+ }
+ return sw.toString();
+ }
+}
diff --git a/src/main/java/emam2someipgroup/App.java b/src/main/java/emam2someipgroup/App.java
deleted file mode 100644
index 3be1b4c6455938b18374e678d381d5d5cbd16fbf..0000000000000000000000000000000000000000
--- a/src/main/java/emam2someipgroup/App.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package emam2someipgroup;
-
-/**
- * Hello world!
- *
- */
-public class App
-{
- public static void main( String[] args )
- {
- System.out.println( "Hello World!" );
- }
-}
diff --git a/src/main/resources/de/monticore/lang/monticar/generator/mqtt/template/PrettyPrint.ftl b/src/main/resources/de/monticore/lang/monticar/generator/mqtt/template/PrettyPrint.ftl
new file mode 100644
index 0000000000000000000000000000000000000000..71033724724222d8f6e3f0b4f094a668c7ff4688
--- /dev/null
+++ b/src/main/resources/de/monticore/lang/monticar/generator/mqtt/template/PrettyPrint.ftl
@@ -0,0 +1,9 @@
+<#--@formatter:off-->
+
+Component name: ${model.getCompName()}
+
+Ports:
+
+<#list model.getPorts() as gen>
+${gen}
+#list>
diff --git a/src/test/java/de/monticore/lang/monticar/generator/someip/AbstractSymtabTest.java b/src/test/java/de/monticore/lang/monticar/generator/someip/AbstractSymtabTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..050d2b56bc49a0afd140179c21b8001b99472d8e
--- /dev/null
+++ b/src/test/java/de/monticore/lang/monticar/generator/someip/AbstractSymtabTest.java
@@ -0,0 +1,154 @@
+package de.monticore.lang.monticar.generator.someip;
+
+/*
+ * Copyright (c) 2015 RWTH Aachen. All rights reserved.
+ *
+ * http://www.se-rwth.de/
+ */
+
+import de.monticore.ModelingLanguageFamily;
+import de.monticore.io.paths.ModelPath;
+import de.monticore.lang.embeddedmontiarc.LogConfig;
+import de.monticore.lang.embeddedmontiarc.embeddedmontiarcmath._symboltable.EmbeddedMontiArcMathLanguage;
+import de.monticore.lang.embeddedmontiarc.tagging.middleware.ros.RosToEmamTagSchema;
+import de.monticore.lang.monticar.Utils;
+import de.monticore.lang.monticar.enumlang._symboltable.EnumLangLanguage;
+import de.monticore.lang.monticar.streamunits._symboltable.StreamUnitsLanguage;
+import de.monticore.lang.monticar.struct._symboltable.StructLanguage;
+import de.monticore.lang.tagging._symboltable.TaggingResolver;
+import de.monticore.symboltable.GlobalScope;
+import de.monticore.symboltable.Scope;
+import org.junit.Assert;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Common methods for symboltable tests
+ */
+public class AbstractSymtabTest {
+
+ public AbstractSymtabTest() {
+ }
+
+ public static TaggingResolver createSymTabAndTaggingResolver(String... modelPath) {
+ Scope scope = createSymTab(modelPath);
+ TaggingResolver taggingResolver = new TaggingResolver(scope, Arrays.asList(modelPath));
+ RosToEmamTagSchema.registerTagTypes(taggingResolver);
+ return taggingResolver;
+ }
+
+ public static Scope createSymTab(String... modelPath) {
+ ModelingLanguageFamily fam = new ModelingLanguageFamily();
+ EmbeddedMontiArcMathLanguage montiArcLanguage = new EmbeddedMontiArcMathLanguage();
+ fam.addModelingLanguage(montiArcLanguage);
+ fam.addModelingLanguage(new StreamUnitsLanguage());
+ fam.addModelingLanguage(new StructLanguage());
+ fam.addModelingLanguage(new EnumLangLanguage());
+ ModelPath mp = new ModelPath(new Path[0]);
+ String[] var4 = modelPath;
+ int var5 = modelPath.length;
+
+ for(int var6 = 0; var6 < var5; ++var6) {
+ String m = var4[var6];
+ mp.addEntry(Paths.get(m));
+ }
+
+ LogConfig.init();
+ GlobalScope scope = new GlobalScope(mp, fam);
+ Utils.addBuiltInTypes(scope);
+ return scope;
+ }
+
+ public static void testFilesAreEqual(List files, String restPath) {
+ assertTrue(files.size() > 0);
+ for (File f : files) {
+ File fileTarget = new File("./src/test/resources/results/" + restPath + f.getName());
+// System.out.println("" + fileTarget.exists() + "Exists:");
+// System.out.println(f.getName() + " " + fileTarget.getName() + "Comparing:");
+ assertTrue(areBothFilesEqual(f, fileTarget));
+ }
+ }
+
+ public static void testFilesAreEqual(List files, String relResultPath, String basePath) {
+ String resultPath = "src/test/resources/results/";
+ for (File f : files) {
+ File tmpFile = new File(basePath);
+ String relativePath = f.getAbsolutePath().replace(tmpFile.getAbsolutePath(), "");
+ File fileTarget = new File(resultPath + relResultPath + relativePath);
+ assertTrue(areBothFilesEqual(f, fileTarget));
+ }
+
+
+ }
+
+ public static boolean areBothFilesEqual(File file1, File file2) {
+ if (!file1.exists()) {
+ Assert.fail("file does not exist: " + file1.getAbsolutePath());
+ return false;
+ }
+ if (!file2.exists()) {
+ Assert.fail("file does not exist: " + file2.getAbsolutePath());
+ return false;
+ }
+ List lines1;
+ List lines2;
+ try {
+ lines1 = Files.readAllLines(file1.toPath());
+ lines2 = Files.readAllLines(file2.toPath());
+ } catch (IOException e) {
+ e.printStackTrace();
+ Assert.fail("IO error: " + e.getMessage());
+ return false;
+ }
+ lines1 = discardEmptyLines(lines1);
+ lines1 = discardCommentLines(lines1);
+ lines2 = discardEmptyLines(lines2);
+ lines2 = discardCommentLines(lines2);
+ if (lines1.size() != lines2.size()) {
+ Assert.fail(
+ "files have different number of lines: "
+ + file1.getAbsolutePath()
+ + " has " + lines1.size()
+ + " lines and " + file2.getAbsolutePath() + " has " + lines2.size() + " lines"
+ );
+ return false;
+ }
+ int len = lines1.size();
+ for (int i = 0; i < len; i++) {
+ String l1 = lines1.get(i);
+ String l2 = lines2.get(i);
+ Assert.assertEquals("files differ in " + i + " line: "
+ + file1.getAbsolutePath()
+ + " has " + l1
+ + " and " + file2.getAbsolutePath() + " has " + l2,
+ l1,
+ l2
+ );
+ }
+ return true;
+ }
+
+ private static List discardEmptyLines(List lines) {
+ return lines.stream()
+ .map(String::trim)
+ .filter(l -> !l.isEmpty())
+ .collect(Collectors.toList());
+ }
+
+ private static List discardCommentLines(List lines) {
+ return lines.stream()
+ .map(String::trim)
+ .filter(l -> !l.startsWith("//"))
+ .collect(Collectors.toList());
+ }
+}
+
diff --git a/src/test/java/de/monticore/lang/monticar/generator/someip/PrettyPrintGenerationTest.java b/src/test/java/de/monticore/lang/monticar/generator/someip/PrettyPrintGenerationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..af498bca078ffd1947896617d5c767ba54b0c46f
--- /dev/null
+++ b/src/test/java/de/monticore/lang/monticar/generator/someip/PrettyPrintGenerationTest.java
@@ -0,0 +1,41 @@
+package de.monticore.lang.monticar.generator.someip;
+
+import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
+import de.monticore.lang.embeddedmontiarc.tagging.middleware.ros.RosToEmamTagSchema;
+import de.monticore.lang.tagging._symboltable.TaggingResolver;
+import de.monticore.lang.embeddedmontiarc.tagging.middleware.someip.SomeIPConnectionSymbol;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.Test;
+
+public class PrettyPrintGenerationTest extends AbstractSymtabTest {
+
+ @Test
+ public void testPrettyPrint() throws IOException {
+
+ TaggingResolver taggingResolver = createSymTabAndTaggingResolver("src/test/resources/");
+
+ // Ros schema is used for now
+ RosToEmamTagSchema.registerTagTypes(taggingResolver);
+
+ // Create component instance and run the generator
+ EMAComponentInstanceSymbol componentInstanceSymbol = taggingResolver.resolve("tests.a.compA", EMAComponentInstanceSymbol.KIND).orElse(null);
+
+ assertNotNull(componentInstanceSymbol);
+
+ GeneratorSomeIP generatorSomeIP = new GeneratorSomeIP();
+
+ // Connect component's ports to topics
+ componentInstanceSymbol.getPortInstance("portA").orElse(null).setMiddlewareSymbol(new SomeIPConnectionSymbol(1,2,3));
+
+ List files = generatorSomeIP.generatePrettyPrint(componentInstanceSymbol);
+
+ //testFilesAreEqual(files, "");
+ }
+
+}
diff --git a/src/test/java/emam2someipgroup/AppTest.java b/src/test/java/emam2someipgroup/AppTest.java
deleted file mode 100644
index 9d911f161f8779e8180520d9542de9513e6787cc..0000000000000000000000000000000000000000
--- a/src/test/java/emam2someipgroup/AppTest.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package emam2someipgroup;
-
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
-{
- /**
- * Rigorous Test :-)
- */
- @Test
- public void shouldAnswerWithTrue()
- {
- assertTrue( true );
- }
-}
diff --git a/src/test/resources/results/echo/ports.txt b/src/test/resources/results/echo/ports.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2596773cae288513485314df090bcc38b57b6988
--- /dev/null
+++ b/src/test/resources/results/echo/ports.txt
@@ -0,0 +1,9 @@
+
+Component name: tests.a.compA
+
+Ports:
+
+portA : incoming (mqtt, topic: /clock)
+portB : incoming (unknown symbol)
+portC : outgoing (unknown symbol)
+portD : outgoing (unknown symbol)
diff --git a/src/test/resources/tests/a/CompA.emam b/src/test/resources/tests/a/CompA.emam
new file mode 100644
index 0000000000000000000000000000000000000000..fa3dcaa9238219b889ef10eb21cfd7fda19f497e
--- /dev/null
+++ b/src/test/resources/tests/a/CompA.emam
@@ -0,0 +1,12 @@
+package tests.a;
+
+component CompA{
+ port in Q portA;
+ port in Q portB;
+ port out Q portC;
+ port out Q portD;
+
+ implementation Math{
+ portA = portD;
+ }
+}