diff --git a/.gitignore b/.gitignore index e53f466f0b7dc8fb4b393e2793d8338f7a8f4dc3..f10fae5a8963f22e2fe0d6d75d6473dc863cc942 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ bin/ *._trace *.xtendbin .DS_Store -target/ \ No newline at end of file +target/ +*.xml_gen diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 31f3a01bf1fbbcb972378b6632f46ad319a74337..ac914057cc0af0eb3b5606bd6b34c9f3549e7d59 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,6 +26,14 @@ # * Verify but don't deploy merge requests. # * Deploy built artifacts from master branch only. +spec: + inputs: + reset-cache: + type: boolean + default: false + +--- + variables: # CI_TARGET_BRANCH: $CI_DEFAULT_BRANCH # CI_TARGET_BRANCH: "ttf-022" @@ -49,6 +57,8 @@ variables: STANDALONE_LOCATION: "plugins/org.etsi.mts.tdl.standalone/target" STANDALONE_NAME: "org.etsi.mts.tdl.standalone-1.0.0-SNAPSHOT-shadow.jar" STANDALONE_PATH: "${STANDALONE_LOCATION}/${STANDALONE_NAME}" + CHANGELOG_PATH: "changelog.txt" + # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work. MAVEN_OPTS: >- @@ -85,12 +95,11 @@ variables: # - when: never - # This template uses the latest Maven 3 release, e.g., 3.8.6, and OpenJDK 8 (LTS) # for verifying and deploying images # Maven 3.8.x REQUIRES HTTPS repositories. # See https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked for more. -image: maven:3.9.6-eclipse-temurin-17 +image: maven:3.9.6-eclipse-temurin-21 # Cache downloaded dependencies and plugins between builds. @@ -100,6 +109,7 @@ image: maven:3.9.6-eclipse-temurin-17 cache: paths: - .m2/repository + - $CI_PROJECT_DIR/.m2/repository # For merge requests do not `deploy` but only run `verify`. # See https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html @@ -152,9 +162,12 @@ build-job: # This job runs in the build stage, which runs first. # - apt-cache gencaches # - apt install -y zip unzip # - zip --help - # - echo "Cleaning caches" - - rm -rf $CI_PROJECT_DIR/.m2/* - - rm -rf ~/.m2/* + - | + if $[[ inputs.reset-cache ]]; then + echo "Cleaning caches" + rm -rf $CI_PROJECT_DIR/.m2/* + rm -rf ~/.m2/* + fi # - ls $CI_PROJECT_DIR/.m2/repository - echo "Compiling the code..." - top -b -n 1 -e m @@ -193,10 +206,15 @@ prepare-job: - echo "VERSION=$VERSION" >> variables.env - echo "PACKAGE_REGISTRY_URL=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/ide/${VERSION}" >> variables.env - echo "PACKAGE_LATEST_URL=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/ide/latest" >> variables.env + - CHANGES=`git log $(git describe --tags --abbrev=0)..HEAD --format='* %h %s'` + - echo "$CHANGES" >> $CHANGELOG_PATH - cat variables.env + - cat $CHANGELOG_PATH artifacts: reports: dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs + paths: + - $CHANGELOG_PATH # https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs/examples/release-assets-as-generic-package/ upload-job: @@ -285,11 +303,14 @@ release-job: - !reference [.default_rules, rules] script: # --description "Published automatically, permalink for installation (valid for 7 days) at https://labs.etsi.org/rep/top/ide/-/releases/permalink/latest/downloads/repository." - - echo $BUILD_JOB_ID + - echo $BUILD_JOB_ID + - CHANGES=`git log $(git describe --tags --abbrev=0)..HEAD --format='* %h %s'` + - echo $CHANGES - | release-cli create --name "Release $VERSION" \ --tag-name $VERSION \ --ref $CI_COMMIT_SHA \ + --description "$CHANGES" \ --assets-link "{\"name\":\"${PACKAGE_NAME} (downloadable archive)\",\"url\":\"${PACKAGE_REGISTRY_URL}/${ARCHIVE_NAME}\",\"filepath\":\"/repository-archive\"}" \ --assets-link "{\"name\":\"${PACKAGE_NAME} (snapshot ${RELEASE_KEY} repository for ${VERSION} (exipres in 7 days))\",\"url\":\"${REPO_PREFIX}/${BUILD_JOB_ID}/${REPO_PATH}\"}" \ --assets-link "{\"name\":\"${PACKAGE_NAME} (latest ${RELEASE_KEY} release repository (permalink))\",\"url\":\"${RELEASE_PAGE}\"}" \ @@ -299,3 +320,32 @@ release-job: # --assets-link "{\"name\":\"${WINDOWS_GUI_JAR}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${WINDOWS_GUI_JAR}\"}" \ # --assets-link "{\"name\":\"${CLI_JAR}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${CLI_JAR}\"}" \ # --assets-link "{\"name\":\"${LIB_JAR}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${LIB_JAR}\"}" + +.release-job-new: + stage: release + image: registry.gitlab.com/gitlab-org/cli:latest + needs: + - job: prepare-job + artifacts: true + - job: build-job + artifacts: true + - job: pages + artifacts: true + rules: + - !reference [.default_rules, rules] + script: + - echo $BUILD_JOB_ID + release: + name: 'Release $VERSION' + tag_name: $VERSION + ref: $CI_COMMIT_SHA + description: $CHANGELOG_PATH + assets: + links: + - name: "${PACKAGE_NAME} (downloadable archive)" + url: "${PACKAGE_REGISTRY_URL}/${ARCHIVE_NAME}" + filepath: "/repository-archive" + - name: "${PACKAGE_NAME} (snapshot ${RELEASE_KEY} repository for ${VERSION} (exipres in 7 days))" + url: "${REPO_PREFIX}/${BUILD_JOB_ID}/${REPO_PATH}" + - name: "${PACKAGE_NAME} (latest ${RELEASE_KEY} release repository (permalink))" + url: "${RELEASE_PAGE}" diff --git a/features/org.etsi.mts.tdl.constraints.feature/feature.xml b/features/org.etsi.mts.tdl.constraints.feature/feature.xml index afccba237ada49e6cbc1230b8e96550d829e6723..47ba1259eeac5a8fee7455993f0a6a31c95ef1d7 100644 --- a/features/org.etsi.mts.tdl.constraints.feature/feature.xml +++ b/features/org.etsi.mts.tdl.constraints.feature/feature.xml @@ -1,7 +1,7 @@ @@ -306,21 +306,11 @@ any resulting litigation. - - - - - - - - - - @@ -335,16 +325,10 @@ any resulting litigation. + version="0.0.0"/> + version="0.0.0"/> diff --git a/features/org.etsi.mts.tdl.converters.feature/feature.xml b/features/org.etsi.mts.tdl.converters.feature/feature.xml index 1b35cf34d5f1c847c862ad3cf803ae1bd0d32412..f81000b0bfa50de57b2cb4e8e38bdf1accb14b03 100644 --- a/features/org.etsi.mts.tdl.converters.feature/feature.xml +++ b/features/org.etsi.mts.tdl.converters.feature/feature.xml @@ -1,7 +1,7 @@ @@ -317,68 +317,35 @@ any resulting litigation. - - - - - - + version="0.0.0"/> - - + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + + diff --git a/features/org.etsi.mts.tdl.model.feature/feature.xml b/features/org.etsi.mts.tdl.model.feature/feature.xml index 86e7d47edf57d02b18449921a6f4cd9f1ec43543..cf2a7e632c4ec8a3343b4935a9f8135ca6901edf 100644 --- a/features/org.etsi.mts.tdl.model.feature/feature.xml +++ b/features/org.etsi.mts.tdl.model.feature/feature.xml @@ -312,20 +312,22 @@ any resulting litigation. + + + + + + + + + version="0.0.0"/> + version="0.0.0"/> diff --git a/features/org.etsi.mts.tdl.tools.to.docx.feature/feature.xml b/features/org.etsi.mts.tdl.tools.to.docx.feature/feature.xml index 2910254f495bf46ebf78a1ef8d8b1ced3fa31424..8d093bc2c80505e1ffe4cc054fc5b7342a4aaad8 100644 --- a/features/org.etsi.mts.tdl.tools.to.docx.feature/feature.xml +++ b/features/org.etsi.mts.tdl.tools.to.docx.feature/feature.xml @@ -1,7 +1,7 @@ @@ -313,7 +313,6 @@ any resulting litigation. - @@ -326,16 +325,10 @@ any resulting litigation. + version="0.0.0"/> + version="0.0.0"/> diff --git a/features/org.etsi.mts.tdl.ttcn3.feature/feature.xml b/features/org.etsi.mts.tdl.ttcn3.feature/feature.xml index a5607b64c65db5a39f0d16681c65080f21f24686..bba0d1438d5851645c325d99983700da2ac67ee8 100644 --- a/features/org.etsi.mts.tdl.ttcn3.feature/feature.xml +++ b/features/org.etsi.mts.tdl.ttcn3.feature/feature.xml @@ -305,38 +305,16 @@ any resulting litigation. - - - - - - - - - - - - - - - - + version="0.0.0"/> + version="0.0.0"/> diff --git a/features/org.etsi.mts.tdl.tx.feature/feature.xml b/features/org.etsi.mts.tdl.tx.feature/feature.xml index 9c4236e2fe9ebe4a9664ff29590011a0df3df41f..faa7355f69b3e091b4848f7bf33b9d8e60d1dc49 100644 --- a/features/org.etsi.mts.tdl.tx.feature/feature.xml +++ b/features/org.etsi.mts.tdl.tx.feature/feature.xml @@ -326,46 +326,34 @@ any resulting litigation. - + - - - - - + + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + + diff --git a/features/org.etsi.mts.tdl.util.feature/feature.xml b/features/org.etsi.mts.tdl.util.feature/feature.xml index 938630714f5b613b17bb1feae508602b8c6da6e7..2b5b3192cde400e3fbfd77ae12be99eb3d825d71 100644 --- a/features/org.etsi.mts.tdl.util.feature/feature.xml +++ b/features/org.etsi.mts.tdl.util.feature/feature.xml @@ -1,7 +1,7 @@ @@ -323,13 +323,7 @@ any resulting litigation. - - - - - - @@ -337,44 +331,18 @@ any resulting litigation. - - + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> - - + version="0.0.0"/> diff --git a/org.etsi.mts.tdl.parent/pom.xml b/org.etsi.mts.tdl.parent/pom.xml index 6107ac1b8a0f9a0a4bd01986adbf2a3776223c80..6f8cdefb3d813926c21b848e94d0515cb72e28e5 100644 --- a/org.etsi.mts.tdl.parent/pom.xml +++ b/org.etsi.mts.tdl.parent/pom.xml @@ -10,6 +10,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs + ../plugins/org.etsi.mts.tdl.model.gen ../plugins/org.etsi.mts.tdl.model ../plugins/org.etsi.mts.tdl.common ../plugins/org.etsi.mts.tdl.helper @@ -51,9 +52,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs ../plugins/org.etsi.mts.tdl.wizards ../plugins/org.etsi.mts.tdl.execution.java ../plugins/org.etsi.mts.tdl.execution.java.codegen - + + ../plugins/org.etsi.mts.tdl.constraints.helper ../plugins/org.etsi.mts.tdl.graphical.labels.data @@ -65,7 +68,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs ../features/org.etsi.mts.tdl.txi.feature ../plugins/org.etsi.mts.tdl.TDLan2.feature ../plugins/org.etsi.mts.tdl.TPLan2.feature + ../features/org.etsi.mts.tdl.converters.feature ../features/org.etsi.mts.tdl.util.feature ../features/org.etsi.mts.tdl.tools.to.docx.feature @@ -79,16 +84,20 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs - 11 - 11 - 3.0.5 - 2.15.0 + 21 + 21 + 4.0.13 + 2.24.0 UTF-8 - 2.32.0 + 2.42.0 true 3.9.0 3.3.0 VERBOSE + + + + -Xmx2048m @@ -151,6 +160,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs false + + org.eclipse.tycho + tycho-surefire-plugin + ${tycho-version} + + + ${tycho.testArgLine} ${platformSystemProperties} ${systemProperties} ${moduleProperties} + + org.apache.maven.plugins @@ -166,6 +184,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs ${basedir}/xtend-gen + + **/* + + + .gitignore + diff --git a/org.etsi.mts.tdl.parent/top.dev.target b/org.etsi.mts.tdl.parent/top.dev.target new file mode 100644 index 0000000000000000000000000000000000000000..b46c28ea864853c6dfaaa655b6d8e1d0b1523ec9 --- /dev/null +++ b/org.etsi.mts.tdl.parent/top.dev.target @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.etsi.mts.tdl.parent/top.target b/org.etsi.mts.tdl.parent/top.target index 6e0817be3794342d825cc016af8d51a365563f39..31811717a4efd6f46d2fd1b334a1b59cfa186f01 100644 --- a/org.etsi.mts.tdl.parent/top.target +++ b/org.etsi.mts.tdl.parent/top.target @@ -1,6 +1,7 @@ + @@ -12,65 +13,102 @@ - - - - + + - - - - - - + + - - - - - - - + + + - + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.TDLan2.feature/feature.xml b/plugins/org.etsi.mts.tdl.TDLan2.feature/feature.xml index b13f4058fe68d12f59bd91e84467f133ee049b4e..40c44c4b9ad469c85b80bdc6dca636a8b2bc5afa 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2.feature/feature.xml +++ b/plugins/org.etsi.mts.tdl.TDLan2.feature/feature.xml @@ -1,7 +1,7 @@ diff --git a/plugins/org.etsi.mts.tdl.TDLan2.ide/.classpath b/plugins/org.etsi.mts.tdl.TDLan2.ide/.classpath index 2d7f28c0f9ce0919184b56530bcc44818b37905a..c1b088dcb866ac99415020baea358575d941ce0c 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2.ide/.classpath +++ b/plugins/org.etsi.mts.tdl.TDLan2.ide/.classpath @@ -3,7 +3,7 @@ - + diff --git a/plugins/org.etsi.mts.tdl.TDLan2.ide/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.TDLan2.ide/.settings/org.eclipse.jdt.core.prefs index 4a7e0723d6efee0525a636a07706c95bbbe13f88..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2.ide/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.TDLan2.ide/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.TDLan2.ide/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.TDLan2.ide/META-INF/MANIFEST.MF index d3fa8c7747198783732be84e3afd0166cd5cb7e7..45a222565d9bbfefb1b104a4fe045804c0a6e6e8 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2.ide/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.TDLan2.ide/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.TDLan2.ide Bundle-Name: org.etsi.mts.tdl.TDLan2.ide Bundle-Vendor: My Company Bundle-Version: 1.0.0.qualifier @@ -10,7 +11,7 @@ Require-Bundle: org.etsi.mts.tdl.TDLan2, org.eclipse.xtext.ide, org.eclipse.xtext.xbase.ide, org.antlr.runtime;bundle-version="[3.2.0,3.2.1)" -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.ide.contentassist.antlr.internal, org.etsi.mts.tdl.ide.contentassist.antlr diff --git a/plugins/org.etsi.mts.tdl.TDLan2.ui/.classpath b/plugins/org.etsi.mts.tdl.TDLan2.ui/.classpath index 2d7f28c0f9ce0919184b56530bcc44818b37905a..c1b088dcb866ac99415020baea358575d941ce0c 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.TDLan2.ui/.classpath @@ -3,7 +3,7 @@ - + diff --git a/plugins/org.etsi.mts.tdl.TDLan2.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.TDLan2.ui/.settings/org.eclipse.jdt.core.prefs index 4a7e0723d6efee0525a636a07706c95bbbe13f88..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.TDLan2.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.TDLan2.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.TDLan2.ui/META-INF/MANIFEST.MF index c3971d2315e7b8ee168d78e4a0dfc9d5e7329aa3..3fea3cdad1499495072f8d0f28babd86e7cc4331 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.TDLan2.ui/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.TDLan2.ui Bundle-Name: org.etsi.mts.tdl.TDLan2.ui Bundle-Vendor: My Company Bundle-Version: 1.0.0.qualifier @@ -19,7 +20,7 @@ Require-Bundle: org.etsi.mts.tdl.TDLan2, org.eclipse.xtend.lib;bundle-version="2.14.0";resolution:=optional, org.eclipse.xtext.xbase.lib;bundle-version="2.14.0" Import-Package: org.apache.log4j -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.ui.contentassist, org.etsi.mts.tdl.TDLan2.ui.internal, org.etsi.mts.tdl.ui.quickfix diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.classpath b/plugins/org.etsi.mts.tdl.TDLan2/.classpath index 8d2d853baecdaec195e0c8889a5f1f0416c4c922..c1b088dcb866ac99415020baea358575d941ce0c 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2/.classpath +++ b/plugins/org.etsi.mts.tdl.TDLan2/.classpath @@ -3,11 +3,7 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TDLan2 Basic.launch b/plugins/org.etsi.mts.tdl.TDLan2/.launch/TDLan2 Basic.launch deleted file mode 100644 index f5b0a18e30338dd06c3fbff3b608417e99f5e097..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TDLan2 Basic.launch +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TDLan2 Complete.launch b/plugins/org.etsi.mts.tdl.TDLan2/.launch/TDLan2 Complete.launch deleted file mode 100644 index a9fbabac980a9ca77e996ab2461919fa05d2457e..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TDLan2 Complete.launch +++ /dev/null @@ -1,981 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (1).launch b/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (1).launch deleted file mode 100644 index 2892d6749c9da9c0d038cb00610f8012987e1f7a..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (1).launch +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TDL.tx and TDL.txi (clean) (2022-12).launch b/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light 2025-09).launch similarity index 77% rename from plugins/org.etsi.mts.tdl.TDLan2/.launch/TDL.tx and TDL.txi (clean) (2022-12).launch rename to plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light 2025-09).launch index c4bc9feea2653cc5a1ad45fcf5607a46ebe2a301..4d8d46c196d3251ba7c1bad994013cc53d847417 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TDL.tx and TDL.txi (clean) (2022-12).launch +++ b/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light 2025-09).launch @@ -4,25 +4,34 @@ - + - + + + + + - - - + + + + + + + + - + @@ -31,18 +40,22 @@ - + - + - - - - + + + + + + + + @@ -51,21 +64,20 @@ - - - - - + + + + + - - - + + @@ -84,23 +96,39 @@ - - - + + + + + + - - - + + + - - + + + + - + + + + + + + + + + + + @@ -110,6 +138,7 @@ + @@ -137,6 +166,7 @@ + @@ -171,43 +201,44 @@ - + - - - - - + + - + + + + + @@ -246,35 +277,41 @@ - - - + + + + + + + + + - - + + + + + + + - - - - - - - + + @@ -283,10 +320,12 @@ + - + + @@ -297,14 +336,20 @@ + + + - - - + + + + + + @@ -328,15 +373,19 @@ + + + + @@ -355,25 +404,15 @@ - - - - - - - - - - + + - - @@ -386,66 +425,59 @@ + - + + + + + + - + + + + - - + - - - - + - - - - - - - - + + + - - - + - - - + - - - @@ -453,6 +485,7 @@ + diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light).launch b/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light).launch deleted file mode 100644 index 45be76d523f262c108e81f635aa2a43a84dc73e7..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light).launch +++ /dev/null @@ -1,550 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light-break).launch b/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light-break).launch deleted file mode 100644 index 22263f85acaa332b55b733d17a0eca7e32637a36..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP (light-break).launch +++ /dev/null @@ -1,486 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP.launch b/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP.launch deleted file mode 100644 index 34bd1e555bb929166355fa5ea43ee0854a13ce75..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.TDLan2/.launch/TOP.launch +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.TDLan2/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.TDLan2/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.TDLan2/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.TDLan2/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.TDLan2/META-INF/MANIFEST.MF index e67467a5dd18995cc99f317a6db587ee585ed8b0..8d38d63f1587eee331bfbafad70176b9e72c281e 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.TDLan2/META-INF/MANIFEST.MF @@ -1,8 +1,17 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.TDLan2 Bundle-Name: org.etsi.mts.tdl.TDLan2 Bundle-Vendor: My Company Bundle-Version: 1.0.0.qualifier +Export-Package: org.etsi.mts.tdl, + org.etsi.mts.tdl.parser.antlr.internal, + org.etsi.mts.tdl.services, + org.etsi.mts.tdl.scoping, + org.etsi.mts.tdl.parser.antlr, + org.etsi.mts.tdl.validation, + org.etsi.mts.tdl.generator, + org.etsi.mts.tdl.serializer Bundle-SymbolicName: org.etsi.mts.tdl.TDLan2; singleton:=true Bundle-ActivationPolicy: lazy Require-Bundle: org.etsi.mts.tdl.model, @@ -14,14 +23,5 @@ Require-Bundle: org.etsi.mts.tdl.model, org.antlr.runtime;bundle-version="[3.2.0,3.2.1)", org.eclipse.xtext.util, org.eclipse.xtend.lib;bundle-version="2.14.0" -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Export-Package: org.etsi.mts.tdl.parser.antlr.internal, - org.etsi.mts.tdl.scoping, - org.etsi.mts.tdl.parser.antlr, - org.etsi.mts.tdl, - org.etsi.mts.tdl.validation, - org.etsi.mts.tdl.generator, - org.etsi.mts.tdl.services, - org.etsi.mts.tdl.serializer, - org.etsi.mts.tdl.formatting2 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Import-Package: org.apache.log4j diff --git a/plugins/org.etsi.mts.tdl.TDLan2/build.properties b/plugins/org.etsi.mts.tdl.TDLan2/build.properties index 388d55f0f68d2339d868d792ad593bd785dd48c0..306924f7707ead00a5e429549c919697ccbf98af 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2/build.properties +++ b/plugins/org.etsi.mts.tdl.TDLan2/build.properties @@ -16,4 +16,4 @@ additional.bundles = org.eclipse.xtext.xbase,\ org.apache.commons.logging,\ org.apache.log4j,\ com.ibm.icu,\ - org.eclipse.xtext.generator + org.eclipse.xtext.xtext.generator diff --git a/plugins/org.etsi.mts.tdl.TDLan2/src/org/etsi/mts/tdl/TDLan2.xtext b/plugins/org.etsi.mts.tdl.TDLan2/src/org/etsi/mts/tdl/TDLan2.xtext index ef8ece3e57e5762a54b7f55b6d23d2e13fac0039..c7b0796a4c5c9a03f9d779dd9726a0b3d1a86b03 100644 --- a/plugins/org.etsi.mts.tdl.TDLan2/src/org/etsi/mts/tdl/TDLan2.xtext +++ b/plugins/org.etsi.mts.tdl.TDLan2/src/org/etsi/mts/tdl/TDLan2.xtext @@ -1405,7 +1405,7 @@ Extension returns tdl::Extension: LiteralValueUse returns tdl::LiteralValueUse: {tdl::LiteralValueUse} - (value=NumberAsIdentifier | value=STRING | intValue=BIGINTEGER | boolValue=BOOLEAN) + (value=STRING | intValue=BIGINTEGER | boolValue=BOOLEAN) ( 'of' 'type' dataType=[tdl::DataType|Identifier] )? diff --git a/plugins/org.etsi.mts.tdl.TPLan2.feature/feature.xml b/plugins/org.etsi.mts.tdl.TPLan2.feature/feature.xml index 56732a88b91f2cd754b4c8ab1b96f2b15ed6fc44..794a6f206fbe432a9ed2524e29d950506aa2e295 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2.feature/feature.xml +++ b/plugins/org.etsi.mts.tdl.TPLan2.feature/feature.xml @@ -1,7 +1,7 @@ diff --git a/plugins/org.etsi.mts.tdl.TPLan2.ide/.classpath b/plugins/org.etsi.mts.tdl.TPLan2.ide/.classpath index 2d7f28c0f9ce0919184b56530bcc44818b37905a..c1b088dcb866ac99415020baea358575d941ce0c 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2.ide/.classpath +++ b/plugins/org.etsi.mts.tdl.TPLan2.ide/.classpath @@ -3,7 +3,7 @@ - + diff --git a/plugins/org.etsi.mts.tdl.TPLan2.ide/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.TPLan2.ide/.settings/org.eclipse.jdt.core.prefs index 4a7e0723d6efee0525a636a07706c95bbbe13f88..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2.ide/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.TPLan2.ide/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.TPLan2.ide/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.TPLan2.ide/META-INF/MANIFEST.MF index 2e86f4b381c994115b351fd35714771fb1c19cc4..34b1fdcb79c5f7404e63830fa4efae7b64802ada 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2.ide/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.TPLan2.ide/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.TPLan2.ide Bundle-Name: org.etsi.mts.tdl.TPLan2.ide Bundle-Vendor: My Company Bundle-Version: 1.0.0.qualifier @@ -10,7 +11,7 @@ Require-Bundle: org.etsi.mts.tdl.TPLan2, org.eclipse.xtext.ide, org.eclipse.xtext.xbase.ide, org.antlr.runtime;bundle-version="[3.2.0,3.2.1)" -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.ide.contentassist.antlr.internal, org.etsi.mts.tdl.ide.contentassist.antlr diff --git a/plugins/org.etsi.mts.tdl.TPLan2.ui/.classpath b/plugins/org.etsi.mts.tdl.TPLan2.ui/.classpath index 2d7f28c0f9ce0919184b56530bcc44818b37905a..c1b088dcb866ac99415020baea358575d941ce0c 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.TPLan2.ui/.classpath @@ -3,7 +3,7 @@ - + diff --git a/plugins/org.etsi.mts.tdl.TPLan2.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.TPLan2.ui/.settings/org.eclipse.jdt.core.prefs index 4a7e0723d6efee0525a636a07706c95bbbe13f88..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.TPLan2.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.TPLan2.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.TPLan2.ui/META-INF/MANIFEST.MF index b0c7ead1980505e9631963f61f384f28f176e6d7..c6923b81908b0dd505b5d1af80f4d47b5e742359 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.TPLan2.ui/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.TPLan2.ui Bundle-Name: org.etsi.mts.tdl.TPLan2.ui Bundle-Vendor: My Company Bundle-Version: 1.0.0.qualifier @@ -19,7 +20,7 @@ Require-Bundle: org.etsi.mts.tdl.TPLan2, org.eclipse.xtend.lib;resolution:=optional, org.eclipse.xtext.xbase.lib Import-Package: org.apache.log4j -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.ui.contentassist, org.etsi.mts.tdl.ui.quickfix, org.etsi.mts.tdl.TPLan2.ui.internal diff --git a/plugins/org.etsi.mts.tdl.TPLan2/.classpath b/plugins/org.etsi.mts.tdl.TPLan2/.classpath index 8d2d853baecdaec195e0c8889a5f1f0416c4c922..c1b088dcb866ac99415020baea358575d941ce0c 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2/.classpath +++ b/plugins/org.etsi.mts.tdl.TPLan2/.classpath @@ -3,11 +3,7 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.TPLan2/.launch/Generate TPLan2 (tplan2) Language Infrastructure.launch b/plugins/org.etsi.mts.tdl.TPLan2/.launch/Generate TPLan2 (tplan2) Language Infrastructure.launch index 13d5830be8ecf047d815c0b20158254993b7029c..6cca4a794cd9c87538539516c03cf3d80e2cf101 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2/.launch/Generate TPLan2 (tplan2) Language Infrastructure.launch +++ b/plugins/org.etsi.mts.tdl.TPLan2/.launch/Generate TPLan2 (tplan2) Language Infrastructure.launch @@ -1,5 +1,6 @@ + @@ -11,6 +12,8 @@ + + diff --git a/plugins/org.etsi.mts.tdl.TPLan2/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.TPLan2/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.TPLan2/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.TPLan2/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.TPLan2/META-INF/MANIFEST.MF index 9b400e1f4634b5b641ad3c910dd9608c933bc2d2..68f11eabec5bbfed6c7a479fc91d73645566a3e6 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.TPLan2/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.TPLan2 Bundle-Name: org.etsi.mts.tdl.TPLan2 Bundle-Vendor: My Company Bundle-Version: 1.0.0.qualifier @@ -14,7 +15,7 @@ Require-Bundle: org.etsi.mts.tdl.model, org.eclipse.xtend.lib, org.antlr.runtime;bundle-version="[3.2.0,3.2.1)", org.etsi.mts.tdl.common -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.scoping, org.etsi.mts.tdl, org.etsi.mts.tdl.validation, diff --git a/plugins/org.etsi.mts.tdl.TPLan2/build.properties b/plugins/org.etsi.mts.tdl.TPLan2/build.properties index 388d55f0f68d2339d868d792ad593bd785dd48c0..306924f7707ead00a5e429549c919697ccbf98af 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2/build.properties +++ b/plugins/org.etsi.mts.tdl.TPLan2/build.properties @@ -16,4 +16,4 @@ additional.bundles = org.eclipse.xtext.xbase,\ org.apache.commons.logging,\ org.apache.log4j,\ com.ibm.icu,\ - org.eclipse.xtext.generator + org.eclipse.xtext.xtext.generator diff --git a/plugins/org.etsi.mts.tdl.TPLan2/src/org/etsi/mts/tdl/TPLan2.xtext b/plugins/org.etsi.mts.tdl.TPLan2/src/org/etsi/mts/tdl/TPLan2.xtext index 0a331818db3832529f442013e80a059d33cf4f0c..0bc9f0e591445fcfe0fadc6469e95ed9b0fc1c07 100644 --- a/plugins/org.etsi.mts.tdl.TPLan2/src/org/etsi/mts/tdl/TPLan2.xtext +++ b/plugins/org.etsi.mts.tdl.TPLan2/src/org/etsi/mts/tdl/TPLan2.xtext @@ -576,7 +576,7 @@ DataContent returns to::Content: ; Identifier returns ecore::EString: - STRING | ID; + STRING | ID | 'attribute' | 'name' | 'value' | 'type'; Qualifier returns tdl::Comment: body=Identifier | body=NumberAsIdentifier diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/ASN1ConverterParsingTest_output.launch b/plugins/org.etsi.mts.tdl.asn1.converter.tests/ASN1ConverterParsingTest_output.launch new file mode 100644 index 0000000000000000000000000000000000000000..3e1292e584ef7fe275b03ab4a8d34c7f7845b9aa --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/ASN1ConverterParsingTest_output.launch @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.asn1.converter.tests/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..0195386580fd0ad051339c79c5bebae58066d5e6 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/META-INF/MANIFEST.MF @@ -0,0 +1,23 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.etsi.mts.tdl.asn1.converter.tests +Bundle-Vendor: ETSI +Bundle-Version: 1.0.0.qualifier +Bundle-SymbolicName: org.etsi.mts.tdl.asn1.converter.tests;singleton:=true +Bundle-ActivationPolicy: lazy +Require-Bundle: org.etsi.mts.tdl.tx, + org.etsi.mts.tdl.model, + org.eclipse.xtext.testing, + org.eclipse.xtext.xbase.testing, + org.eclipse.xtext.xbase.lib, + org.eclipse.xtend.lib, + junit-jupiter-api, + junit-jupiter-engine, + junit-platform-launcher, + junit-platform-engine, + org.eclipse.equinox.app, + org.junit, + org.hamcrest.core +Bundle-RequiredExecutionEnvironment: JavaSE-21 +Bundle-ClassPath: . +Export-Package: org.etsi.mts.tdl.asn1.converter.tests;x-internal=true diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/README.md b/plugins/org.etsi.mts.tdl.asn1.converter.tests/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1a423e6bbc7dc5fc0df7d5d84eb34fbbe4217c77 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/README.md @@ -0,0 +1,171 @@ +# ASN.1 to TDL Converter Tests + +Automated tests that validate the syntactic correctness of TDL output produced by the ASN.1-to-TDL converter (`ttf-045`). + +## How it works + +1. The test factory scans `src/asn1/` for inputs (see two modes below) +2. For each input, the Python converter is invoked: + ``` + python asn1_cli.py convert --format tdl -o + ``` +3. The generated TDL is parsed by the Xtext-based TDL parser (`org.etsi.mts.tdl.tx`) +4. The test asserts that parsing produces no syntax errors +5. On failure, the full generated TDL is dumped with line numbers alongside error details + +### Single-file mode + +`.asn` / `.asn1` files placed directly in `src/asn1/` are each converted independently. Use this for self-contained schemas without cross-module imports. + +### Grouped mode + +Subdirectories in `src/asn1/` are passed as a whole to the converter. The converter scans the directory recursively, compiles all schemas together, and produces one combined TDL output. Use this for schemas that have cross-module `IMPORTS`. + +``` +src/asn1/ + Rocket.asn → single-file test + ITS/ → grouped test (all files compiled together) + CAM-PDU-Descriptions.asn + DENM-PDU-Descriptions.asn + ETSI-ITS-CDD.asn +``` + +## Prerequisites + +- **Java 21** (for the Xtext parser / JUnit 5 runtime) +- **Python 3** with the converter's dependencies installed + +### Setting up a virtual environment (recommended) + +```bash +cd D:/Work/ETSI/TOP/ttf-045 +python -m venv .venv + +# Activate — pick one: +source .venv/Scripts/activate # Git Bash on Windows +.venv\Scripts\activate # cmd / PowerShell on Windows +source .venv/bin/activate # Linux / macOS + +pip install -r requirements.txt +``` + +The test auto-detects a `.venv` directory inside the converter project — no extra configuration needed. If the venv is elsewhere, point to it explicitly: +``` +-Dpython.executable=/path/to/.venv/Scripts/python +``` + +## Running the tests + +### From Eclipse + +Right-click `ASN1ConverterParsingTest.java` > **Run As** > **JUnit Test** + +If the converter directory is not found automatically, add a VM argument: +``` +-Dasn1.converter.dir=D:/Work/ETSI/TOP/ttf-045 +``` + +### Headless / CLI (recommended for quick runs) + +The tests can be run standalone using the provided `build.xml` via the Eclipse `antRunner` application. This is the fastest way to run the tests (~15s) as it only compiles and runs this project. + +**Command:** + +```bash +java -jar /plugins/org.eclipse.equinox.launcher_.jar \ + -nosplash \ + -application org.eclipse.ant.core.antRunner \ + -buildfile build.xml \ +``` + +To override configuration, pass `-D` flags to the `java` command: +```bash +java -Dasn1.converter.dir=/path/to/ttf-045 -Dpython.executable=python3 \ + -jar /plugins/org.eclipse.equinox.launcher_.jar \ + -nosplash \ + -application org.eclipse.ant.core.antRunner \ + -buildfile build.xml \ +``` + +Test results are printed to the console and also written to `TEST-*.txt` and `TEST-*.xml` files in the project directory. + +### From Maven (full reactor build) + +Maven/Tycho requires a full reactor build because of cascading OSGi dependencies. Run from the parent project (`org.etsi.mts.tdl.parent`): + +```bash +mvn verify +``` + +## Configuration + +All settings are optional and controlled via system properties (`-D`): + +| Property | Default | Description | +|-----------------------|----------------------------------|--------------------------------------------| +| `python.executable` | venv in converter dir, else `python` | Python interpreter path | +| `asn1.converter.dir` | auto-resolved relative to CWD | Path to the `ttf-045` converter project | +| `asn1.test.files` | `src/asn1` within this project | Folder containing ASN.1 input files | +| `converter.timeout` | `120` (seconds) | Max time to wait for the converter process | + +### Path resolution details + +The test auto-resolves paths based on `user.dir` (the JVM working directory). If a system property is set, it takes precedence and the auto-resolution is skipped. + +**Converter directory** (`asn1.converter.dir`) — tries in order: + +| Working directory | Resolved path | Scenario | +|----------------------------------|------------------------|------------------------------| +| `.../ide/plugins/` | `../../../ttf-045` | Running from Eclipse | +| `.../ide` | `../../ttf-045` | Running from IDE root | +| `.../TOP` | `ttf-045` | Running from workspace root | + +**Python executable** (`python.executable`) — tries in order: + +1. System property `-Dpython.executable=...` +2. `/.venv/Scripts/python.exe` (Windows venv) +3. `/.venv/bin/python` (Unix venv) +4. `python` on `PATH` + +**ASN.1 test files** (`asn1.test.files`) — tries in order: + +1. System property `-Dasn1.test.files=...` +2. Classpath resource `/asn1` +3. `/src/asn1` +4. `/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1` + +The expected workspace layout is: +``` +TOP/ + ttf-045/ Converter project (with optional .venv/) + ide/ + plugins/ + org.etsi.mts.tdl.asn1.converter.tests/ + src/asn1/ ASN.1 test inputs +``` + +## Adding test cases + +No code changes required — the `@TestFactory` discovers inputs automatically. + +- **Single file:** drop a self-contained `.asn` / `.asn1` file into `src/asn1/` +- **Group with imports:** create a subdirectory under `src/asn1/` and place all related schemas in it + +To test against an external ASN.1 collection: +``` +-Dasn1.test.files="D:/Work/ETSI/TOP/ASN.1 specs/Modules/ITS/r2" +``` + +## Project structure + +``` +org.etsi.mts.tdl.asn1.converter.tests/ + META-INF/MANIFEST.MF OSGi bundle manifest + pom.xml Maven/Tycho build config + src/ + asn1/ + Rocket.asn Initial test input (simple schema) + org/etsi/mts/tdl/asn1/converter/tests/ + ASN1ConverterParsingTest.java Test class (@TestFactory) + ASN1ConverterInjectorProvider.java Xtext/Guice setup +``` diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/build.properties b/plugins/org.etsi.mts.tdl.asn1.converter.tests/build.properties similarity index 68% rename from plugins/org.etsi.mts.tdl.openapi2tdl/build.properties rename to plugins/org.etsi.mts.tdl.asn1.converter.tests/build.properties index 56d776555503f2905e0642aae5be7938371a965d..b107977f4ed7c4ae7bc2725947b2e16e5b30f4b1 100644 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/build.properties +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/build.properties @@ -1,4 +1,3 @@ source.. = src/ -output.. = target/classes/ bin.includes = META-INF/,\ . diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/build.xml b/plugins/org.etsi.mts.tdl.asn1.converter.tests/build.xml new file mode 100644 index 0000000000000000000000000000000000000000..84b5f3c35d405d2dc07318ebd47de4399506b5b4 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/build.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/pom.xml b/plugins/org.etsi.mts.tdl.asn1.converter.tests/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..4d5d21b9fa6d19ea32bd326a7be2362ff4fdb51a --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/pom.xml @@ -0,0 +1,32 @@ + + 4.0.0 + + org.etsi.mts.tdl + org.etsi.mts.tdl.parent + 1.0.0-SNAPSHOT + ../../org.etsi.mts.tdl.parent + + org.etsi.mts.tdl.asn1.converter.tests + eclipse-test-plugin + + ASN.1 to TDL Converter Tests + + + + + org.eclipse.xtend + xtend-maven-plugin + + + org.eclipse.tycho + tycho-surefire-plugin + + false + false + false + + + + + diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/CAM-PDU-Descriptions.asn b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/CAM-PDU-Descriptions.asn new file mode 100644 index 0000000000000000000000000000000000000000..3380c93a7584cc2396bb7686e5f23e6a9df976db --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/CAM-PDU-Descriptions.asn @@ -0,0 +1,218 @@ +CAM-PDU-Descriptions {itu-t (0) identified-organization (4) etsi (0) itsDomain (5) wg1 (1) camPduRelease2 (103900) major-version-2 (2) minor-version-1 (1)} + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS +ItsPduHeader, CauseCodeV2, ReferencePosition, AccelerationControl, Curvature, CurvatureCalculationMode, Heading, LanePosition, EmergencyPriority, EmbarkationStatus, Speed, +DriveDirection, AccelerationComponent, StationType, ExteriorLights, DangerousGoodsBasic, SpecialTransportType, LightBarSirenInUse, +VehicleRole, VehicleLength, VehicleWidth, Path, RoadworksSubCauseCode, ClosedLanes, TrafficRule, SpeedLimit, SteeringWheelAngle, PerformanceClass, YawRate, +PtActivation, ProtectedCommunicationZonesRSU, CenDsrcTollingZone, GenerationDeltaTime, BasicContainer, BrakeControl, VehicleHeight2, WiperStatus, +GeneralizedLanePositions, PathPredictedList, CartesianAngle, Wgs84Angle, StabilityChangeIndication, VruSubProfileBicyclist, VruMovementControl, +BasicLaneConfiguration, PolygonalLine, MetaInformation, ConfidenceLevels, VehicleMovementControl + +FROM ETSI-ITS-CDD {itu-t (0) identified-organization (4) etsi (0) itsDomain (5) wg1 (1) 102894 cdd (2) major-version-4 (4) minor-version-2 (2)} WITH SUCCESSORS +; + +CAM ::= SEQUENCE { + header ItsPduHeader (WITH COMPONENTS {... , protocolVersion (2), messageId(cam)}), + cam CamPayload +} + +CamPayload ::= SEQUENCE { + generationDeltaTime GenerationDeltaTime, + camParameters CamParameters +} + +CamParameters ::= SEQUENCE { + basicContainer BasicContainer, + highFrequencyContainer HighFrequencyContainer, + lowFrequencyContainer LowFrequencyContainer OPTIONAL, + specialVehicleContainer SpecialVehicleContainer OPTIONAL, + ..., + extensionContainers WrappedExtensionContainers OPTIONAL +} + +HighFrequencyContainer ::= CHOICE { + basicVehicleContainerHighFrequency BasicVehicleContainerHighFrequency, + rsuContainerHighFrequency RSUContainerHighFrequency, + ... +} + + LowFrequencyContainer ::= CHOICE { + basicVehicleContainerLowFrequency BasicVehicleContainerLowFrequency (WITH COMPONENTS {..., pathHistory (SIZE (0..23))}), + ... +} + +SpecialVehicleContainer ::= CHOICE { + publicTransportContainer PublicTransportContainer, + specialTransportContainer SpecialTransportContainer, + dangerousGoodsContainer DangerousGoodsContainer, + roadWorksContainerBasic RoadWorksContainerBasic, + rescueContainer RescueContainer, + emergencyContainer EmergencyContainer, + safetyCarContainer SafetyCarContainer, + ... +} + +BasicVehicleContainerHighFrequency ::= SEQUENCE { + heading Heading, + speed Speed, + driveDirection DriveDirection, + vehicleLength VehicleLength, + vehicleWidth VehicleWidth, + longitudinalAcceleration AccelerationComponent, + curvature Curvature, + curvatureCalculationMode CurvatureCalculationMode, + yawRate YawRate, + accelerationControl AccelerationControl OPTIONAL, + lanePosition LanePosition OPTIONAL, + steeringWheelAngle SteeringWheelAngle OPTIONAL, + lateralAcceleration AccelerationComponent OPTIONAL, + verticalAcceleration AccelerationComponent OPTIONAL, + performanceClass PerformanceClass OPTIONAL, + cenDsrcTollingZone CenDsrcTollingZone OPTIONAL +} + +BasicVehicleContainerLowFrequency ::= SEQUENCE { + vehicleRole VehicleRole, + exteriorLights ExteriorLights, + pathHistory Path +} + +PublicTransportContainer ::= SEQUENCE { + embarkationStatus EmbarkationStatus, + ptActivation PtActivation OPTIONAL +} + +SpecialTransportContainer ::= SEQUENCE { + specialTransportType SpecialTransportType, + lightBarSirenInUse LightBarSirenInUse +} + +DangerousGoodsContainer ::= SEQUENCE { + dangerousGoodsBasic DangerousGoodsBasic +} + +RoadWorksContainerBasic ::= SEQUENCE { + roadworksSubCauseCode RoadworksSubCauseCode OPTIONAL, + lightBarSirenInUse LightBarSirenInUse, + closedLanes ClosedLanes OPTIONAL +} + +RescueContainer ::= SEQUENCE { + lightBarSirenInUse LightBarSirenInUse +} + +EmergencyContainer ::= SEQUENCE { + lightBarSirenInUse LightBarSirenInUse, + incidentIndication CauseCodeV2 OPTIONAL, + emergencyPriority EmergencyPriority OPTIONAL +} + +SafetyCarContainer ::= SEQUENCE { + lightBarSirenInUse LightBarSirenInUse, + incidentIndication CauseCodeV2 OPTIONAL, + trafficRule TrafficRule OPTIONAL, + speedLimit SpeedLimit OPTIONAL +} + + +RSUContainerHighFrequency ::= SEQUENCE { + protectedCommunicationZonesRSU ProtectedCommunicationZonesRSU OPTIONAL, + ... +} + + +EXTENSION-CONTAINER-ID-AND-TYPE ::= CLASS { + &id ExtensionContainerId UNIQUE, + &Type +} WITH SYNTAX {&Type IDENTIFIED BY &id} + + +ExtensionContainerId ::= INTEGER (1..16,...) + + +twoWheelerContainer ExtensionContainerId ::= 1 +eHorizonLocationSharingContainer ExtensionContainerId ::= 2 +veryLowFrequencyContainer ExtensionContainerId ::= 3 +pathPredictionContainer ExtensionContainerId ::= 4 +generalizedLanePositionsContainer ExtensionContainerId ::= 5 +vehicleMovementControlContainer ExtensionContainerId ::= 6 + + +ExtensionContainers EXTENSION-CONTAINER-ID-AND-TYPE ::= { + {TwoWheelerContainer IDENTIFIED BY twoWheelerContainer} | + {EHorizonLocationSharingContainer IDENTIFIED BY eHorizonLocationSharingContainer} | + {VeryLowFrequencyContainer IDENTIFIED BY veryLowFrequencyContainer} | + {PathPredictionContainer IDENTIFIED BY pathPredictionContainer} | + {GeneralizedLanePositionsContainer IDENTIFIED BY generalizedLanePositionsContainer} | + {VehicleMovementControlContainer IDENTIFIED BY vehicleMovementControlContainer}, + ... +} + + +WrappedExtensionContainer ::= SEQUENCE { + containerId EXTENSION-CONTAINER-ID-AND-TYPE.&id( {ExtensionContainers} ), + containerData EXTENSION-CONTAINER-ID-AND-TYPE.&Type( {ExtensionContainers}{@containerId} ) +} + + +WrappedExtensionContainers ::= SEQUENCE SIZE(1..8,...) OF WrappedExtensionContainer + + +TwoWheelerContainer ::= SEQUENCE { + typeSpecificInformation TwoWheelerTypeSpecificInformation OPTIONAL, + rollAngle CartesianAngle OPTIONAL, + orientation Wgs84Angle OPTIONAL, + stabilityChangeIndication StabilityChangeIndication OPTIONAL, + ... +} + + +TwoWheelerTypeSpecificInformation ::= CHOICE { + cyclist CyclistTypeSpecificInformation, + ... +} + + +CyclistTypeSpecificInformation ::= SEQUENCE { + vruSubProfileBicyclist VruSubProfileBicyclist (unavailable | bicyclist | e-scooter | pedelec | speed-pedelec | roadbike | childrensbike) OPTIONAL, + vruMovementControl VruMovementControl OPTIONAL, + ... +} + + +EHorizonLocationSharingContainer ::= SEQUENCE { + segmentAhead PolygonalLine, + nodeProbabilities ConfidenceLevels OPTIONAL, + segmentBehind PolygonalLine, + laneLevelDetails BasicLaneConfiguration OPTIONAL, + segmentSource MetaInformation (WITH COMPONENTS {..., confidenceValue ABSENT}) OPTIONAL, + ... +} + + +VeryLowFrequencyContainer ::= SEQUENCE { + vehicleHeight VehicleHeight2 OPTIONAL, + wiperStatus WiperStatus OPTIONAL, + brakeControl BrakeControl OPTIONAL, + ... +} + + +PathPredictionContainer ::= PathPredictedList + + +GeneralizedLanePositionsContainer ::= GeneralizedLanePositions + + +VehicleMovementControlContainer ::= SEQUENCE { + vehicleMovementControl VehicleMovementControl, + ... +} + + +END + diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/DENM-PDU-Descriptions.asn b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/DENM-PDU-Descriptions.asn new file mode 100644 index 0000000000000000000000000000000000000000..dd8f52e0f82baa66e71ca424df7a2d31dc470720 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/DENM-PDU-Descriptions.asn @@ -0,0 +1,160 @@ +DENM-PDU-Description {itu-t (0) identified-organization (4) etsi (0) itsDomain (5) wg1 (1) denmPduRelease2 (103831) + major-version-2 (2) minor-version-2 (2)} + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + +ActionId, ActionIdList, CauseCodeV2, ClosedLanes, DangerousGoodsExtended, DeltaReferencePosition, DeltaTimeMilliSecondPositive, DeltaTimeSecond, +EnergyStorageType, EventZone, GeneralizedLanePositions, HeightLonCarr, InformationQuality, ItsPduHeader, IvimReferences, LanePosition, +LightBarSirenInUse, ItineraryPath, MapReferences, MetaInformation, NumberOfOccupants, ObjectFace, OccupiedLanesWithConfidence, PerceivedObject, +Position1d, PosLonCarr, PosCentMass, PositionOfPillars, PositioningSolutionType, PosFrontAx, PositionOfOccupants, PathPredictedList, +RequestResponseIndication, ReferencePosition, RestrictedTypes, RoadConfigurationSectionList, RoadType, StandardLength3b,StandardLength12b, +StationType, Speed, SpeedLimit, StationId, StationarySince, TimestampIts, Traces, TracesExtended, TrafficDirection, TrafficRule, TurningRadius, +Temperature, VehicleMass, VehicleIdentification, Wgs84Angle, WheelBaseVehicle + +FROM ETSI-ITS-CDD {itu-t (0) identified-organization (4) etsi (0) itsDomain (5) wg1 (1) ts (102894) cdd (2) + major-version-4 (4) minor-version-2 (2)} WITH SUCCESSORS +; + + +DENM ::= SEQUENCE { + header ItsPduHeader (WITH COMPONENTS {... , protocolVersion (2), messageId(denm)}), + denm DenmPayload +} + + +DenmPayload ::= SEQUENCE { + management ManagementContainer, + situation SituationContainer OPTIONAL, + location LocationContainer OPTIONAL, + alacarte AlacarteContainer OPTIONAL +} +((WITH COMPONENTS {..., management (WITH COMPONENTS {..., termination ABSENT}), situation PRESENT, location PRESENT}) | + (WITH COMPONENTS {..., management (WITH COMPONENTS {..., termination PRESENT}), situation ABSENT, location ABSENT, alacarte ABSENT})) + + +ManagementContainer ::= SEQUENCE { + actionId ActionId, + detectionTime TimestampIts, + referenceTime TimestampIts, + termination Termination OPTIONAL, + eventPosition ReferencePosition, + awarenessDistance StandardLength3b OPTIONAL, + trafficDirection TrafficDirection OPTIONAL, + validityDuration DeltaTimeSecond DEFAULT defaultValidity, + transmissionInterval DeltaTimeMilliSecondPositive OPTIONAL, + stationType StationType, + ... +} + + +SituationContainer ::= SEQUENCE { + informationQuality InformationQuality, + eventType CauseCodeV2, + linkedCause CauseCodeV2 OPTIONAL, + eventZone EventZone OPTIONAL, + ..., +[[ linkedDenms ActionIdList OPTIONAL, + eventEnd Position1d OPTIONAL ]] +} + ((WITH COMPONENTS {..., eventZone PRESENT, eventEnd ABSENT}) | + (WITH COMPONENTS {..., eventZone ABSENT, eventEnd PRESENT}) | + (WITH COMPONENTS {..., eventZone ABSENT, eventEnd ABSENT})) + + + + +LocationContainer ::= SEQUENCE { + eventSpeed Speed OPTIONAL, + eventPositionHeading Wgs84Angle OPTIONAL, + detectionZonesToEventPosition Traces, + roadType RoadType OPTIONAL, + ..., +[[ lanePositions GeneralizedLanePositions OPTIONAL, + occupiedLanes OccupiedLanesWithConfidence OPTIONAL, + linkedIvims IvimReferences OPTIONAL, + linkedMapems MapReferences OPTIONAL, + detectionZonesToSpecifiedEventPoint TracesExtended OPTIONAL, + predictedPaths PathPredictedList OPTIONAL ]] +} + + +ImpactReductionContainer ::= SEQUENCE { + heightLonCarrLeft HeightLonCarr, + heightLonCarrRight HeightLonCarr, + posLonCarrLeft PosLonCarr, + posLonCarrRight PosLonCarr, + positionOfPillars PositionOfPillars, + posCentMass PosCentMass, + wheelBaseVehicle WheelBaseVehicle, + turningRadius TurningRadius, + posFrontAx PosFrontAx, + positionOfOccupants PositionOfOccupants, + vehicleMass VehicleMass, + requestResponseIndication RequestResponseIndication +} + + +PreCrashContainer ::= SEQUENCE { + perceivedPreCrashObject PerceivedObject, + objectStationId StationId OPTIONAL, + timeToCollision DeltaTimeMilliSecondPositive OPTIONAL, + impactSection ObjectFace OPTIONAL, + estimatedBrakingDistance StandardLength12b OPTIONAL, + ... +} + + +RoadConfigurationContainer ::= SEQUENCE { + roadConfigurationConfidence MetaInformation, + roadConfigurationSectionList RoadConfigurationSectionList, + ... +} + + +RoadWorksContainerExtended ::= SEQUENCE { + lightBarSirenInUse LightBarSirenInUse OPTIONAL, + closedLanes ClosedLanes OPTIONAL, + restriction RestrictedTypes OPTIONAL, + speedLimit SpeedLimit OPTIONAL, + incidentIndication CauseCodeV2 OPTIONAL, + recommendedPath ItineraryPath OPTIONAL, + startingPointSpeedLimit DeltaReferencePosition OPTIONAL, + trafficFlowRule TrafficRule OPTIONAL, + referenceDenms ActionIdList OPTIONAL +} + + +StationaryVehicleContainer ::= SEQUENCE { + stationarySince StationarySince OPTIONAL, + stationaryCause CauseCodeV2 OPTIONAL, + carryingDangerousGoods DangerousGoodsExtended OPTIONAL, + numberOfOccupants NumberOfOccupants OPTIONAL, + vehicleIdentification VehicleIdentification OPTIONAL, + energyStorageType EnergyStorageType OPTIONAL +} + + +AlacarteContainer ::= SEQUENCE { + lanePosition LanePosition OPTIONAL, + impactReduction ImpactReductionContainer OPTIONAL, + externalTemperature Temperature OPTIONAL, + roadWorks RoadWorksContainerExtended OPTIONAL, + positioningSolution PositioningSolutionType OPTIONAL, + stationaryVehicle StationaryVehicleContainer OPTIONAL, + ..., +[[ roadConfiguration RoadConfigurationContainer OPTIONAL, + preCrash PreCrashContainer OPTIONAL ]] +} + + +defaultValidity INTEGER ::= 600 + + + +Termination ::= ENUMERATED {isCancellation(0), isNegation (1)} + +END diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/ETSI-ITS-CDD.asn b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/ETSI-ITS-CDD.asn new file mode 100644 index 0000000000000000000000000000000000000000..e28630f5fb6fcab78f24ac479431e1f902249601 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/ITS/ETSI-ITS-CDD.asn @@ -0,0 +1,7778 @@ +ETSI-ITS-CDD {itu-t (0) identified-organization (4) etsi (0) itsDomain (5) wg1 (1) 102894 cdd (2) major-version-4 (4) minor-version-2 (2)} + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +------------------------------------------ +-- Specification of CDD Data Elements: +------------------------------------------ + +/** + * This DE indicates a change of acceleration. + * + * The value shall be set to: + * - 0 - `accelerate` - if the magnitude of the horizontal velocity vector increases. + * - 1 - `decelerate` - if the magnitude of the horizontal velocity vector decreases. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 +*/ +AccelerationChange::= ENUMERATED { + accelerate (0), + decelerate (1) +} + +/** + * This DE indicates the acceleration confidence value which represents the estimated absolute accuracy of an acceleration value with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 101`) if the confidence value is equal to or less than n x 0,1 m/s^2, and greater than (n-1) x 0,1 m/s^2, + * - `101` if the confidence value is out of range i.e. greater than 10 m/s^2, + * - `102` if the confidence value is unavailable. + * + * The value 0 shall not be used. + * + * @note: The fact that an acceleration value is received with confidence value set to `unavailable(102)` can be caused by several reasons, such as: + * - the sensor cannot deliver the accuracy at the defined confidence level because it is a low-end sensor, + * - the sensor cannot calculate the accuracy due to lack of variables, or + * - there has been a vehicle bus (e.g. CAN bus) error. + * In all 3 cases above, the acceleration value may be valid and used by the application. + * + * @note: If an acceleration value is received and its confidence value is set to `outOfRange(101)`, it means that the value is not valid and therefore cannot be trusted. Such value is not useful for the application. + * + * @unit 0,1 m/s^2 + * @category: Kinematic information + * @revision: Description revised in V2.1.1 + */ +AccelerationConfidence ::= INTEGER { + outOfRange (101), + unavailable (102) +} (0..102) + +/** + * This DE indicates the status of the controlling mechanisms for longitudinal movement of the vehicle. + * The data may be provided via the in-vehicle network. It indicates whether a specific in-vehicle + * acceleration control system is engaged or not. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 - `brakePedalEngaged` - Driver is stepping on the brake pedal, + * - 1 - `gasPedalEngaged` - Driver is stepping on the gas pedal, + * - 2 - `emergencyBrakeEngaged` - emergency brake system is engaged, + * - 3 - `collisionWarningEngaged`- collision warning system is engaged, + * - 4 - `accEngaged` - ACC is engaged, + * - 5 - `cruiseControlEngaged` - cruise control is engaged, + * - 6 - `speedLimiterEngaged` - speed limiter is engaged. + * + * Otherwise (for example when the corresponding system is not available due to non equipped system + * or information is unavailable), the corresponding bit shall be set to 0. + * + * @note: The system engagement condition is OEM specific and therefore out of scope of the present document. + * @category: Vehicle information + * @revision: V1.3.1, description revised in V2.3.1 + */ +AccelerationControl ::= BIT STRING { + brakePedalEngaged (0), + gasPedalEngaged (1), + emergencyBrakeEngaged (2), + collisionWarningEngaged (3), + accEngaged (4), + cruiseControlEngaged (5), + speedLimiterEngaged (6) +} (SIZE(7)) + +/** + * This DE represents the extension of DE AccelerationControl and should only be used together with DE AccelerationControl. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 - `rearCrossTrafficAlertEngaged` - rear cross traffic alert system is engaged + * - 1 - `emergencyBrakeRearEngaged` - emergency brake system for rear driving is engaged + * - 2 - `assistedParkingLongitudinalEngaged` - assisted parking system (longitudinal control) is engaged + * + * Otherwise (for example when the corresponding system is not available due to non-equipped system + * or information is unavailable), the corresponding bit shall be set to 0. + * + * @category: Vehicle information + * @revision: Created in V2.3.1 + */ +AccelerationControlExtension::= BIT STRING { + rearCrossTrafficAlertEngaged (0), + emergencyBrakeRearEngaged (1), + assistedParkingLongitudinalEngaged (2) +} (SIZE(3,...)) + + +/** + * This DE represents the magnitude of the acceleration vector in a defined coordinate system. + * + * The value shall be set to: + * - `0` to indicate no acceleration, + * - `n` (`n > 0` and `n < 160`) to indicate acceleration equal to or less than n x 0,1 m/s^2, and greater than (n-1) x 0,1 m/s^2, + * - `160` for acceleration values greater than 15,9 m/s^2, + * - `161` when the data is unavailable. + * + * @unit 0,1 m/s^2 + * @category: Kinematic information + * @revision: Created in V2.1.1 +*/ +AccelerationMagnitudeValue ::= INTEGER { + positiveOutOfRange (160), + unavailable (161) +} (0.. 161) + +/** + * This DE represents the value of an acceleration component in a defined coordinate system. + * + * The value shall be set to: + * - `-160` for acceleration values equal to or less than -16 m/s^2, + * - `n` (`n > -160` and `n <= 0`) to indicate negative acceleration equal to or less than n x 0,1 m/s^2, and greater than (n-1) x 0,1 m/s^2, + * - `n` (`n > 0` and `n < 160`) to indicate positive acceleration equal to or less than n x 0,1 m/s^2, and greater than (n-1) x 0,1 m/s^2, + * - `160` for acceleration values greater than 15,9 m/s^2, + * - `161` when the data is unavailable. + * + * @note: the formula for values > -160 and <160 results in rounding up to the next value. Zero acceleration is indicated using n=0. + * @unit 0,1 m/s^2 + * @category: Kinematic information + * @revision: Created in V2.1.1 +*/ +AccelerationValue ::= INTEGER { + negativeOutOfRange (-160), + positiveOutOfRange (160), + unavailable (161) +} (-160 .. 161) + + +/** + * This DE indicates an access technology. + * + * The value shall be set to: + * - `0`: in case of any access technology class, + * - `1`: in case of ITS-G5 access technology class, + * - `2`: in case of LTE-V2X access technology class, + * - `3`: in case of NR-V2X access technology class. + * + * @category: Communication information + * @revision: Created in V2.1.1 + */ +AccessTechnologyClass ::= ENUMERATED { + any (0), + itsg5Class (1), + ltev2xClass (2), + nrv2xClass (3), + ... +} + +/** + * This DE represents the value of the sub cause code of the @ref CauseCode `accident`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case the information on the sub cause of the accident is unavailable, + * - 1 - `multiVehicleAccident` - in case more than two vehicles are involved in accident, + * - 2 - `heavyAccident` - in case the airbag of the vehicle involved in the accident is triggered, + * the accident requires important rescue and/or recovery work, + * - 3 - `accidentInvolvingLorry` - in case the accident involves a lorry, + * - 4 - `accidentInvolvingBus` - in case the accident involves a bus, + * - 5 - `accidentInvolvingHazardousMaterials`- in case the accident involves hazardous material, + * - 6 - `accidentOnOppositeLane` - in case the accident happens on opposite lanes, + * - 7 - `unsecuredAccident` - in case the accident is not secured, + * - 8 - `assistanceRequested` - in case rescue and assistance are requested, + * - 9-255 - reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +AccidentSubCauseCode ::= INTEGER { + unavailable (0), + multiVehicleAccident (1), + heavyAccident (2), + accidentInvolvingLorry (3), + accidentInvolvingBus (4), + accidentInvolvingHazardousMaterials (5), + accidentOnOppositeLane (6), + unsecuredAccident (7), + assistanceRequested (8) +} (0..255) + +/** + * This DE represents the value of the sub cause code of the @ref CauseCode `adverseWeatherCondition-Adhesion`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case information on the cause of the low road adhesion is unavailable, + * - 1 - `heavyFrostOnRoad`- in case the low road adhesion is due to heavy frost on the road, + * - 2 - `fuelOnRoad` - in case the low road adhesion is due to fuel on the road, + * - 3 - `mudOnRoad` - in case the low road adhesion is due to mud on the road, + * - 4 - `snowOnRoad` - in case the low road adhesion is due to snow on the road, + * - 5 - `iceOnRoad` - in case the low road adhesion is due to ice on the road, + * - 6 - `blackIceOnRoad` - in case the low road adhesion is due to black ice on the road, + * - 7 - `oilOnRoad` - in case the low road adhesion is due to oil on the road, + * - 8 - `looseChippings` - in case the low road adhesion is due to loose gravel or stone fragments detached from a road surface or from a hazard, + * - 9 - `instantBlackIce` - in case the low road adhesion is due to instant black ice on the road surface, + * - 10 - `roadsSalted` - when the low road adhesion is due to salted road, + * - 11-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +AdverseWeatherCondition-AdhesionSubCauseCode ::= INTEGER { + unavailable (0), + heavyFrostOnRoad (1), + fuelOnRoad (2), + mudOnRoad (3), + snowOnRoad (4), + iceOnRoad (5), + blackIceOnRoad (6), + oilOnRoad (7), + looseChippings (8), + instantBlackIce (9), + roadsSalted (10) +} (0..255) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `adverseWeatherCondition-ExtremeWeatherCondition`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case information on the type of extreme weather condition is unavailable, + * - 1 - `strongWinds` - in case the type of extreme weather condition is strong wind, + * - 2 - `damagingHail`- in case the type of extreme weather condition is damaging hail, + * - 3 - `hurricane` - in case the type of extreme weather condition is hurricane, + * - 4 - `thunderstorm`- in case the type of extreme weather condition is thunderstorm, + * - 5 - `tornado` - in case the type of extreme weather condition is tornado, + * - 6 - `blizzard` - in case the type of extreme weather condition is blizzard. + * - 7-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +AdverseWeatherCondition-ExtremeWeatherConditionSubCauseCode ::= INTEGER { + unavailable (0), + strongWinds (1), + damagingHail (2), + hurricane (3), + thunderstorm (4), + tornado (5), + blizzard (6) +} (0..255) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `adverseWeatherCondition-Precipitation`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case information on the type of precipitation is unavailable, + * - 1 - `heavyRain` - in case the type of precipitation is heavy rain, + * - 2 - `heavySnowfall` - in case the type of precipitation is heavy snow fall, + * - 3 - `softHail` - in case the type of precipitation is soft hail. + * - 4-255 - are reserved for future usage + * + * @category: Traffic information + * @revision: V1.3.1 + */ +AdverseWeatherCondition-PrecipitationSubCauseCode ::= INTEGER { + unavailable (0), + heavyRain (1), + heavySnowfall (2), + softHail (3) +} (0..255) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `adverseWeatherCondition-Visibility`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case information on the cause of low visibility is unavailable, + * - 1 - `fog` - in case the cause of low visibility is fog, + * - 2 - `smoke` - in case the cause of low visibility is smoke, + * - 3 - `heavySnowfall` - in case the cause of low visibility is heavy snow fall, + * - 4 - `heavyRain` - in case the cause of low visibility is heavy rain, + * - 5 - `heavyHail` - in case the cause of low visibility is heavy hail, + * - 6 - `lowSunGlare` - in case the cause of low visibility is sun glare, + * - 7 - `sandstorms` - in case the cause of low visibility is sand storm, + * - 8 - `swarmsOfInsects`- in case the cause of low visibility is swarm of insects. + * - 9-255 - are reserved for future usage + * + * @category: Traffic information + * @revision: V1.3.1 + */ +AdverseWeatherCondition-VisibilitySubCauseCode ::= INTEGER { + unavailable (0), + fog (1), + smoke (2), + heavySnowfall (3), + heavyRain (4), + heavyHail (5), + lowSunGlare (6), + sandstorms (7), + swarmsOfInsects (8) +} (0..255) + +/** + * This DE represents the air humidity in tenths of percent. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 1001`) indicates that the applicable value is equal to or less than n x 0,1 percent and greater than (n-1) x 0,1 percent. + * - `1001` indicates that the air humidity is unavailable. + * + * @category: Basic information + * @unit: 0,1 % + * @revision: created in V2.1.1 + */ +AirHumidity ::= INTEGER { + oneHundredPercent (1000), + unavailable (1001) +} (1..1001) + +/** + * This DE indicates the altitude confidence value which represents the estimated absolute accuracy of an altitude value of a geographical point with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - 0 - `alt-000-01` - if the confidence value is equal to or less than 0,01 metre, + * - 1 - `alt-000-02` - if the confidence value is equal to or less than 0,02 metre and greater than 0,01 metre, + * - 2 - `alt-000-05` - if the confidence value is equal to or less than 0,05 metre and greater than 0,02 metre, + * - 3 - `alt-000-10` - if the confidence value is equal to or less than 0,1 metre and greater than 0,05 metre, + * - 4 - `alt-000-20` - if the confidence value is equal to or less than 0,2 metre and greater than 0,1 metre, + * - 5 - `alt-000-50` - if the confidence value is equal to or less than 0,5 metre and greater than 0,2 metre, + * - 6 - `alt-001-00` - if the confidence value is equal to or less than 1 metre and greater than 0,5 metre, + * - 7 - `alt-002-00` - if the confidence value is equal to or less than 2 metres and greater than 1 metre, + * - 8 - `alt-005-00` - if the confidence value is equal to or less than 5 metres and greater than 2 metres, + * - 9 - `alt-010-00` - if the confidence value is equal to or less than 10 metres and greater than 5 metres, + * - 10 - `alt-020-00` - if the confidence value is equal to or less than 20 metres and greater than 10 metres, + * - 11 - `alt-050-00` - if the confidence value is equal to or less than 50 metres and greater than 20 metres, + * - 12 - `alt-100-00` - if the confidence value is equal to or less than 100 metres and greater than 50 metres, + * - 13 - `alt-200-00` - if the confidence value is equal to or less than 200 metres and greater than 100 metres, + * - 14 - `outOfRange` - if the confidence value is out of range, i.e. greater than 200 metres, + * - 15 - `unavailable` - if the confidence value is unavailable. + * + * @note: The fact that an altitude value is received with confidence value set to `unavailable(15)` can be caused + * by several reasons, such as: + * - the sensor cannot deliver the accuracy at the defined confidence level because it is a low-end sensor, + * - the sensor cannot calculate the accuracy due to lack of variables, or + * - there has been a vehicle bus (e.g. CAN bus) error. + * In all 3 cases above, the altitude value may be valid and used by the application. + * + * @note: If an altitude value is received and its confidence value is set to `outOfRange(14)`, it means that the + * altitude value is not valid and therefore cannot be trusted. Such value is not useful for the application. + * + * @category: GeoReference information + * @revision: Description revised in V2.1.1 + */ +AltitudeConfidence ::= ENUMERATED { + alt-000-01 (0), + alt-000-02 (1), + alt-000-05 (2), + alt-000-10 (3), + alt-000-20 (4), + alt-000-50 (5), + alt-001-00 (6), + alt-002-00 (7), + alt-005-00 (8), + alt-010-00 (9), + alt-020-00 (10), + alt-050-00 (11), + alt-100-00 (12), + alt-200-00 (13), + outOfRange (14), + unavailable (15) +} + +/** + * This DE represents the altitude value in a WGS84 coordinate system. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `-100 000` if the altitude is equal to or less than -1 000 m, + * - `n` (`n > -100 000` and `n < 800 000`) if the altitude is equal to or less than n x 0,01 metre and greater than (n-1) x 0,01 metre, + * - `800 000` if the altitude greater than 7 999,99 m, + * - `800 001` if the information is not available. + * + * @note: the range of this DE does not use the full binary encoding range, but all reasonable values are covered. In order to cover all possible altitude ranges a larger encoding would be necessary. + * @unit: 0,01 metre + * @category: GeoReference information + * @revision: Description revised in V2.1.1 (definition of 800 000 has slightly changed) + */ +AltitudeValue ::= INTEGER { + negativeOutOfRange (-100000), + postiveOutOfRange (800000), + unavailable (800001) +} (-100000..800001) + +/** + * This DE indicates the angle confidence value which represents the estimated absolute accuracy of an angle value with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 126`) if the accuracy is equal to or less than n * 0,1 degrees and greater than (n-1) x * 0,1 degrees, + * - `126` if the accuracy is out of range, i.e. greater than 12,5 degrees, + * - `127` if the accuracy information is not available. + * + * @unit: 0,1 degrees + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +AngleConfidence ::= INTEGER { + outOfRange (126), + unavailable (127) +} (1..127) + +/** + * This DE indicates the angular speed confidence value which represents the estimated absolute accuracy of an angular speed value with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * For correlation computation, maximum interval levels can be assumed. + * + * The value shall be set to: + * - 0 - `degSec-01` - if the accuracy is equal to or less than 1 degree/second, + * - 1 - `degSec-02` - if the accuracy is equal to or less than 2 degrees/second and greater than 1 degree/second, + * - 2 - `degSec-05` - if the accuracy is equal to or less than 5 degrees/second and greater than 2 degrees/second, + * - 3 - `degSec-10` - if the accuracy is equal to or less than 10 degrees/second and greater than 5 degrees/second, + * - 4 - `degSec-20` - if the accuracy is equal to or less than 20 degrees/second and greater than 10 degrees/second, + * - 5 - `degSec-50` - if the accuracy is equal to or less than 50 degrees/second and greater than 20 degrees/second, + * - 6 - `outOfRange` - if the accuracy is out of range, i.e. greater than 50 degrees/second, + * - 7 - `unavailable` - if the accuracy information is unavailable. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 +*/ +AngularSpeedConfidence ::= ENUMERATED { + degSec-01 (0), + degSec-02 (1), + degSec-05 (2), + degSec-10 (3), + degSec-20 (4), + degSec-50 (5), + outOfRange (6), + unavailable (7) +} + +/** + * This DE indicates the angular acceleration confidence value which represents the estimated accuracy of an angular acceleration value with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * For correlation computation, maximum interval levels shall be assumed. + * + * The value shall be set to: + * - 0 - `degSecSquared-01` - if the accuracy is equal to or less than 1 degree/second^2, + * - 1 - `degSecSquared-02` - if the accuracy is equal to or less than 2 degrees/second^2 and greater than 1 degree/second^2, + * - 2 - `degSecSquared-05` - if the accuracy is equal to or less than 5 degrees/second^2 and greater than 1 degree/second^2, + * - 3 - `degSecSquared-10` - if the accuracy is equal to or less than 10 degrees/second^2 and greater than 5 degrees/second^2, + * - 4 - `degSecSquared-20` - if the accuracy is equal to or less than 20 degrees/second^2 and greater than 10 degrees/second^2, + * - 5 - `degSecSquared-50` - if the accuracy is equal to or less than 50 degrees/second^2 and greater than 20 degrees/second^2, + * - 6 - `outOfRange` - if the accuracy is out of range, i.e. greater than 50 degrees/second^2, + * - 7 - `unavailable` - if the accuracy information is unavailable. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 +*/ +AngularAccelerationConfidence ::= ENUMERATED { + degSecSquared-01 (0), + degSecSquared-02 (1), + degSecSquared-05 (2), + degSecSquared-10 (3), + degSecSquared-20 (4), + degSecSquared-50 (5), + outOfRange (6), + unavailable (7) +} + +/** + * This DE indicates the status of the controlling mechanisms for the lateral and combined lateral and longitudinal movements of the vehicle. + * The data may be provided via the in-vehicle network. It indicates whether a specific in-vehicle + * acceleration control system combined with steering of the direction of the vehicle is engaged or not. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 - `emergencySteeringSystemEngaged` - emergency steering system is engaged, + * - 1 - `autonomousEmergencySteeringEngaged` - autonomous emergency steering system is engaged, + * - 2 - `automaticLaneChangeEngaged` - automatic lane change system is engaged, + * - 3 - `laneKeepingAssistEngaged` - lane keeping assist is engaged, + * - 4 - `assistedParkingLateralEngaged` - assisted parking system (lateral control) is engaged, + * - 5 - `emergencyAssistEngaged` - emergency assist (lateral and longitudinal control) is engaged. + * + * Otherwise (for example when the corresponding system is not available due to non-equipped system or information is unavailable), + * the corresponding bit shall be set to 0. + * + * @category: Vehicle information + * @revision: Created in V2.3.1 +*/ +AutomationControl::= BIT STRING { + emergencySteeringSystemEngaged (0), + autonomousEmergencySteeringEngaged (1), + automaticLaneChangeEngaged (2), + laneKeepingAssistEngaged (3), + assistedParkingLateralEngaged (4), + emergencyAssistEngaged (5) +}(SIZE(6,...)) + +/** + * This DE indicates the number of axles of a passing train. + * + * The value shall be set to: + * - `n` (`n > 2` and `n < 1001`) indicates that the train has n x axles, + * - `1001`indicates that the number of axles is out of range, + * - `1002` the information is unavailable. + * + * + * @unit: Number of axles + * @category: Vehicle information + * @revision: Created in V2.1.1 +*/ +AxlesCount ::= INTEGER{ + outOfRange (1001), + unavailable (1002) +} (2..1002) + +/** + * This DE represents the measured uncompensated atmospheric pressure. + * + * The value shall be set to: + * - `2999` indicates that the applicable value is less than 29990 Pa, + * - `n` (`n > 2999` and `n <= 12000`) indicates that the applicable value is equal to or less than n x 10 Pa and greater than (n-1) x 10 Pa, + * - `12001` indicates that the values is greater than 120000 Pa, + * - `12002` indicates that the information is not available. + * + * @category: Basic information + * @unit: 10 Pascal + * @revision: Created in V2.1.1 +*/ +BarometricPressure ::= INTEGER{ + outOfRangelower (2999), + outOfRangeUpper (12001), + unavailable (12002) +} (2999..12002) + + +/** + * This DE indicates the cardinal number of bogies of a train. + * + * The value shall be set to: + * - `n` (`n > 1` and `n < 100`) indicates that the train has n x bogies, + * - `100`indicates that the number of bogies is out of range, + * - `101` the information is unavailable. + * + * @unit: Number of bogies + * @category: Vehicle information + * @revision: Created in V2.1.1 +*/ +BogiesCount ::= INTEGER{ + outOfRange (100), + unavailable (101) +} (2..101) + +/** + * This DE indicates the status of the vehicle´s brake control system during an externally defined period of time. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 `abs` - the anti-lock braking system is engaged or has been engaged, + * - 1 `tcs` - the traction control system is engaged or has been engaged, + * - 2 `esc` - the electronic stability control system is engaged or has been engaged. + * + * Otherwise (for example when the corresponding system is not available due to non equipped system + * or information is unavailable), the corresponding bit shall be set to 0. + * + * @category: Vehicle information + * @revision: created in V2.3.1 + */ +BrakeControl::= BIT STRING { + abs (0), + tcs (1), + esc (2) +} (SIZE(3, ...)) + +/** + * The DE represents a cardinal number that counts the size of a set. + * + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +CardinalNumber1B ::= INTEGER(0..255) + +/** + * The DE represents a cardinal number that counts the size of a set. + * + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +CardinalNumber3b ::= INTEGER(1..8) + +/** + * This DE represents an angle value described in a local Cartesian coordinate system, per default counted positive in + * a right-hand local coordinate system from the abscissa. + * + * The value shall be set to: + * - `n` (`n >= 0` and `n < 3600`) if the angle is equal to or less than n x 0,1 degrees, and greater than (n-1) x 0,1 degrees, + * - `3601` if the information is not available. + * + * The value 3600 shall not be used. + * + * @unit 0,1 degrees + * @category: Basic information + * @revision: Created in V2.1.1, description and value for 3601 corrected in V2.2.1 +*/ +CartesianAngleValue ::= INTEGER { + valueNotUsed (3600), + unavailable (3601) +} (0..3601) + +/** + * This DE represents an angular acceleration value described in a local Cartesian coordinate system, per default counted positive in + * a right-hand local coordinate system from the abscissa. + * + * The value shall be set to: + * - `-255` if the acceleration is equal to or less than -255 degrees/s^2, + * - `n` (`n > -255` and `n < 255`) if the acceleration is equal to or less than n x 1 degree/s^2, + and greater than `(n-1)` x 0,01 degree/s^2, + * - `255` if the acceleration is greater than 254 degrees/s^2, + * - `256` if the information is unavailable. + * + * @unit: degree/s^2 (degrees per second squared) + * @category: Kinematic information + * @revision: Created in V2.1.1 +*/ +CartesianAngularAccelerationComponentValue ::= INTEGER { + negativeOutOfRange (-255), + positiveOutOfRange (255), + unavailable (256) +} (-255..256) + +/** + * This DE represents an angular velocity component described in a local Cartesian coordinate system, per default counted positive in + * a right-hand local coordinate system from the abscissa. + * + * The value shall be set to: + * - `-255` if the velocity is equal to or less than -255 degrees/s, + * - `n` (`n > -255` and `n < 255`) if the velocity is equal to or less than n x 1 degree/s, and greater than (n-1) x 1 degree/s, + * - `255` if the velocity is greater than 254 degrees/s, + * - `256` if the information is unavailable. + * + * @unit: degree/s + * @category: Kinematic information + * @revision: Created in V2.1.1 +*/ +CartesianAngularVelocityComponentValue ::= INTEGER { + negativeOutofRange (-255), + positiveOutOfRange (255), + unavailable (256) +} (-255..256) + +/** + *The DE represents the value of the cause code of an event. + * + * The value shall be set to: + * - 0 - reserved for future use, + * - 1 - `trafficCondition` - in case the type of event is an abnormal traffic condition, + * - 2 - `accident` - in case the type of event is a road accident, + * - 3 - `roadworks` - in case the type of event is roadwork, + * - 4 - reserved for future usage, + * - 5 - `impassability` - in case the type of event is unmanaged road blocking, referring to any + * blocking of a road, partial or total, which has not been adequately + * secured and signposted, + * - 6 - `adverseWeatherCondition-Adhesion` - in case the type of event is low adhesion, + * - 7 - `aquaplaning` - danger of aquaplaning on the road, + * - 8 - reserved for future usage, + * - 9 - `hazardousLocation-SurfaceCondition` - in case the type of event is abnormal road surface condition, + * - 10 - `hazardousLocation-ObstacleOnTheRoad` - in case the type of event is obstacle on the road, + * - 11 - `hazardousLocation-AnimalOnTheRoad` - in case the type of event is animal on the road, + * - 12 - `humanPresenceOnTheRoad` - in case the type of event is presence of human vulnerable road user on the road, + * - 13 - reserved for future usage, + * - 14 - `wrongWayDriving` - in case the type of the event is vehicle driving in wrong way, + * - 15 - `rescueAndRecoveryWorkInProgress` - in case the type of event is rescue and recovery work for accident or for a road hazard in progress, + * - 16 - reserved for future usage, + * - 17 - `adverseWeatherCondition-ExtremeWeatherCondition`- in case the type of event is extreme weather condition, + * - 18 - `adverseWeatherCondition-Visibility` - in case the type of event is low visibility, + * - 19 - `adverseWeatherCondition-Precipitation` - in case the type of event is precipitation, + * - 20 - `violence` - in case the the type of event is human violence on or near the road, + * - 21-25 - reserved for future usage, + * - 26 - `slowVehicle` - in case the type of event is slow vehicle driving on the road, + * - 27 - `dangerousEndOfQueue` - in case the type of event is dangerous end of vehicle queue, + * - 28 - `publicTransportVehicleApproaching - in case the type of event is a public transport vehicle approaching, with a priority defined by applicable traffic regulations, + * - 29-90 - are reserved for future usage, + * - 91 - `vehicleBreakdown` - in case the type of event is break down vehicle on the road, + * - 92 - `postCrash` - in case the type of event is a detected crash, + * - 93 - `humanProblem` - in case the type of event is human health problem in vehicles involved in traffic, + * - 94 - `stationaryVehicle` - in case the type of event is stationary vehicle, + * - 95 - `emergencyVehicleApproaching` - in case the type of event is an approaching vehicle operating on a mission for which the applicable + traffic regulations provide it with defined priority rights in traffic. + * - 96 - `hazardousLocation-DangerousCurve` - in case the type of event is dangerous curve, + * - 97 - `collisionRisk` - in case the type of event is a collision risk, + * - 98 - `signalViolation` - in case the type of event is signal violation, + * - 99 - `dangerousSituation` - in case the type of event is dangerous situation in which autonomous safety system in vehicle + * is activated, + * - 100 - `railwayLevelCrossing` - in case the type of event is a railway level crossing. + * - 101-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1, value 28 added in V2.2.1, definition of values 12 and 95 changed in V2.2.1 + */ +CauseCodeType ::= INTEGER { + trafficCondition (1), + accident (2), + roadworks (3), + impassability (5), + adverseWeatherCondition-Adhesion (6), + aquaplaning (7), + hazardousLocation-SurfaceCondition (9), + hazardousLocation-ObstacleOnTheRoad (10), + hazardousLocation-AnimalOnTheRoad (11), + humanPresenceOnTheRoad (12), + wrongWayDriving (14), + rescueAndRecoveryWorkInProgress (15), + adverseWeatherCondition-ExtremeWeatherCondition (17), + adverseWeatherCondition-Visibility (18), + adverseWeatherCondition-Precipitation (19), + violence (20), + slowVehicle (26), + dangerousEndOfQueue (27), + publicTransportVehicleApproaching (28), + vehicleBreakdown (91), + postCrash (92), + humanProblem (93), + stationaryVehicle (94), + emergencyVehicleApproaching (95), + hazardousLocation-DangerousCurve (96), + collisionRisk (97), + signalViolation (98), + dangerousSituation (99), + railwayLevelCrossing (100) +} (0..255) + +/** + * This DF represents the value of a cartesian coordinate with a range of -30,94 metres to +10,00 metres. + * + * The value shall be set to: + * - `3094` if the longitudinal offset is out of range, i.e. less than or equal to -30,94 metres, + * - `n` (`n > -3 094` and `n < 1 001`) if the longitudinal offset information is equal to or less than n x 0,01 metre and more than (n-1) x 0,01 metre, + * - `1001` if the longitudinal offset is out of range, i.e. greater than 10 metres. + * + * @unit 0,01 m + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +CartesianCoordinateSmall::= INTEGER { + negativeOutOfRange (-3094), + positiveOutOfRange (1001) +} (-3094..1001) + +/** + * This DF represents the value of a cartesian coordinate with a range of -327,68 metres to +327,66 metres. + * + * The value shall be set to: + * - `-32 768` if the longitudinal offset is out of range, i.e. less than or equal to -327,68 metres, + * - `n` (`n > -32 768` and `n < 32 767`) if the longitudinal offset information is equal to or less than n x 0,01 metre and more than (n-1) x 0,01 metre, + * - `32 767` if the longitudinal offset is out of range, i.e. greater than + 327,66 metres. + * + * @unit 0,01 m + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +CartesianCoordinate::= INTEGER{ + negativeOutOfRange (-32768), + positiveOutOfRange (32767) +} (-32768..32767) + +/** + * This DF represents the value of a cartesian coordinate with a range of -1 310,72 metres to +1 310,70 metres. + * + * The value shall be set to: + * - `-131072` if the longitudinal offset is out of range, i.e. less than or equal to -1 310,72 metres, + * - `n` (`n > 131 072` and `n < 131 071`) if the longitudinal offset information is equal to or less than n x 0,01 metre and more than (n-1) x 0,01 metre, + * - `131 071` if the longitudinal offset is out of range, i.e. greater than + 1 310,70 metres. + * + * @unit 0,01 m + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +CartesianCoordinateLarge::= INTEGER{ + negativeOutOfRange (-131072), + positiveOutOfRange (131071) +} (-131072..131071) + +/** + * This DE represents the ID of a CEN DSRC tolling zone. + * + * @category: Communication information + * @revision: V1.3.1 + * @note: this DE is deprecated and shall not be used anymore. + */ +CenDsrcTollingZoneID::= ProtectedZoneId + +/** + * This DE indicates the reason why a cluster leader intends to break up the cluster. + * + * The value shall be set to: + * - 0 - `notProvided` - if the information is not provided, + * - 1 - `clusteringPurposeCompleted` - if the cluster purpose has been completed, + * - 2 - `leaderMovedOutOfClusterBoundingBox` - if the leader moved out of the cluster's bounding box, + * - 3 - `joiningAnotherCluster` - if the cluster leader is about to join another cluster, + * - 4 - `enteringLowRiskAreaBasedOnMaps` - if the cluster is entering an area idenrified as low risk based on the use of maps, + * - 5 - `receptionOfCpmContainingCluster` - if the leader received a Collective Perception Message containing information about the same cluster. + * - 6 to 15 - are reserved for future use. + * + * @category: Cluster information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 +*/ +ClusterBreakupReason ::= INTEGER { + notProvided (0), + clusteringPurposeCompleted (1), + leaderMovedOutOfClusterBoundingBox (2), + joiningAnotherCluster (3), + enteringLowRiskAreaBasedOnMaps (4), + receptionOfCpmContainingCluster (5) +}(0..15) + +/** + * This DE indicates the reason why a cluster participant is leaving the cluster. + * + * The value shall be set to: + * - 0 - `notProvided ` - if the information is not provided, + * - 1 - `clusterLeaderLost` - if the cluster leader cannot be found anymore, + * - 2 - `clusterDisbandedByLeader` - if the cluster has been disbanded by the leader, + * - 3 - `outOfClusterBoundingBox` - if the participants moved out of the cluster's bounding box, + * - 4 - `outOfClusterSpeedRange` - if the cluster speed moved out of a defined range, + * - 5 - `joiningAnotherCluster` - if the participant is joining another cluster, + * - 6 - `cancelledJoin` - if the participant is cancelling a joining procedure, + * - 7 - `failedJoin` - if the participant failed to join the cluster, + * - 8 - `safetyCondition` - if a safety condition applies. + * - 9 to 15 - are reserved for future use + * + * @category: Cluster information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 + */ +ClusterLeaveReason ::= INTEGER { + notProvided (0), + clusterLeaderLost (1), + clusterDisbandedByLeader (2), + outOfClusterBoundingBox (3), + outOfClusterSpeedRange (4), + joiningAnotherCluster (5), + cancelledJoin (6), + failedJoin (7), + safetyCondition (8) +}(0..15) + +/** + * This DE represents the sub cause codes of the @ref CauseCode `collisionRisk`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case information on the type of collision risk is unavailable, + * - 1 - `longitudinalCollisionRisk` - in case the type of detected collision risk is longitudinal collision risk, + * e.g. forward collision or face to face collision, + * - 2 - `crossingCollisionRisk` - in case the type of detected collision risk is crossing collision risk, + * - 3 - `lateralCollisionRisk` - in case the type of detected collision risk is lateral collision risk, + * - 4 - `vulnerableRoadUser` - in case the type of detected collision risk involves vulnerable road users + * e.g. pedestrians or bicycles. + * - 5 - `collisionRiskWithPedestrian` - in case the type of detected collision risk involves at least one pedestrian, + * - 6 - `collisionRiskWithCyclist` - in case the type of detected collision risk involves at least one cyclist (and no pedestrians), + * - 7 - `collisionRiskWithMotorVehicle` - in case the type of detected collision risk involves at least one motor vehicle (and no pedestrians or cyclists), + * - 8-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1, values 5-7 assigned in V2.2.1 + */ +CollisionRiskSubCauseCode ::= INTEGER { + unavailable (0), + longitudinalCollisionRisk (1), + crossingCollisionRisk (2), + lateralCollisionRisk (3), + vulnerableRoadUser (4), + collisionRiskWithPedestrian (5), + collisionRiskWithCyclist (6), + collisionRiskWithMotorVehicle (7) +}(0..255) + +/** + * This DE represents a confidence level in percentage. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 101`) : for the confidence level in %, + * - `101` : in case the confidence level is not available. + * + * @unit Percent + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +ConfidenceLevel ::= INTEGER { + unavailable (101) +} (1..101) + +/** + * This DE indicates the coordinate confidence value which represents the estimated absolute accuracy of a position coordinate with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 4095`) if the confidence value is is equal to or less than n x 0,01 metre, and greater than (n-1) x 0,01 metre, + * - `4095` if the confidence value is greater than 40,94 metres, + * - `4096` if the confidence value is not available. + * + * @unit 0,01 m + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +CoordinateConfidence ::= INTEGER { + outOfRange (4095), + unavailable (4096) +} (1..4096) + +/** + * This DE represents the Bravais-Pearson correlation value for each cell of a lower triangular correlation matrix. + * + * The value shall be set to: + * - `-100` in case of full negative correlation, + * - `n` (`n > -100` and `n < 0`) if the correlation is negative and equal to n x 100, + * - `0` in case of no correlation, + * - `n` (`n > 0` and `n < 100`) if the correlation is positive and equal to n x 100, + * - `100` in case of full positive correlation, + * - `101` in case the correlation information is unavailable. + * + * @unit: the value is scaled by 100 + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +CorrelationCellValue ::= INTEGER { + full-negative-correlation (-100), + no-correlation (0), + full-positive-correlation (100), + unavailable (101) +} (-100..101) + +/** + * This DE represents an ISO 3166-1 [25] country code encoded using ITA-2 encoding. + * + * @category: Basic information + * @revision: Created in V2.2.1 based on ISO 14816 [23] +*/ +CountryCode ::= BIT STRING(SIZE(10)) + +/** + * The DE describes whether the yaw rate is used to calculate the curvature for a curvature value. + * + * The value shall be set to: + * - 0 - `yawRateUsed` - if the yaw rate is used, + * - 1 - `yawRateNotUsed` - if the yaw rate is not used, + * - 2 - `unavailable` - if the information of curvature calculation mode is unknown. + * + * @category: Vehicle information + * @revision: V1.3.1 + */ +CurvatureCalculationMode ::= ENUMERATED { + yawRateUsed (0), + yawRateNotUsed (1), + unavailable (2), + ... +} + +/** + * This DE indicates the acceleration confidence value which represents the estimated absolute accuracy range of a curvature value with a confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - 0 - `onePerMeter-0-00002` - if the confidence value is less than or equal to 0,00002 m-1, + * - 1 - `onePerMeter-0-0001` - if the confidence value is less than or equal to 0,0001 m-1 and greater than 0,00002 m-1, + * - 2 - `onePerMeter-0-0005` - if the confidence value is less than or equal to 0,0005 m-1 and greater than 0,0001 m-1, + * - 3 - `onePerMeter-0-002` - if the confidence value is less than or equal to 0,002 m-1 and greater than 0,0005 m-1, + * - 4 - `nePerMeter-0-01` - if the confidence value is less than or equal to 0,01 m-1 and greater than 0,002 m-1, + * - 5 - `nePerMeter-0-1` - if the confidence value is less than or equal to 0,1 m-1 and greater than 0,01 m-1, + * - 6 - `outOfRange` - if the confidence value is out of range, i.e. greater than 0,1 m-1, + * - 7 - `unavailable` - if the confidence value is not available. + * + * @note: The fact that a curvature value is received with confidence value set to `unavailable(7)` can be caused by + * several reasons, such as: + * - the sensor cannot deliver the accuracy at the defined confidence level because it is a low-end sensor, + * - the sensor cannot calculate the accuracy due to lack of variables, or + * - there has been a vehicle bus (e.g. CAN bus) error. + * In all 3 cases above, the curvature value may be valid and used by the application. + * + * @note: If a curvature value is received and its confidence value is set to `outOfRange(6)`, it means that the curvature value is not valid + * and therefore cannot be trusted. Such value is not useful for the application. + * + * @category: Vehicle information + * @revision: Description revised in V2.1.1 +*/ +CurvatureConfidence ::= ENUMERATED { + onePerMeter-0-00002 (0), + onePerMeter-0-0001 (1), + onePerMeter-0-0005 (2), + onePerMeter-0-002 (3), + onePerMeter-0-01 (4), + onePerMeter-0-1 (5), + outOfRange (6), + unavailable (7) +} + +/** + * This DE describes vehicle turning curve with the following information: + * ``` + * Value = 1 / Radius * 10000 + * ``` + * wherein radius is the vehicle turning curve radius in metres. + * + * Positive values indicate a turning curve to the left hand side of the driver. + * It corresponds to the vehicle coordinate system as defined in ISO 8855 [21]. + * + * The value shall be set to: + * - `-1023` for values smaller than -1023, + * - `n` (`n > -1023` and `n < 0`) for negative values equal to or less than `n`, and greater than `(n-1)`, + * - `0` when the vehicle is moving straight, + * - `n` (`n > 0` and `n < 1022`) for positive values equal to or less than `n`, and greater than `(n-1)`, + * - `1022`, for values greater than 1021, + * - `1023`, if the information is not available. + * + * @note: The present DE is limited to vehicle types as defined in ISO 8855 [21]. + * + * @unit: 1 over 10 000 metres + * @category: Vehicle information + * @revision: description revised in V2.1.1 (the definition of value 1022 has changed slightly) + */ +CurvatureValue ::= INTEGER { + outOfRangeNegative (-1023), + straight (0), + outOfRangePositive (1022), + unavailable (1023) +} (-1023..1023) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `dangerousEndOfQueue`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case information on the type of dangerous queue is unavailable, + * - 1 - `suddenEndOfQueue`- in case a sudden end of queue is detected, e.g. due to accident or obstacle, + * - 2 - `queueOverHill` - in case the dangerous end of queue is detected on the road hill, + * - 3 - `queueAroundBend` - in case the dangerous end of queue is detected around the road bend, + * - 4 - `queueInTunnel` - in case queue is detected in tunnel, + * - 5-255 - reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +DangerousEndOfQueueSubCauseCode ::= INTEGER { + unavailable (0), + suddenEndOfQueue (1), + queueOverHill (2), + queueAroundBend (3), + queueInTunnel (4) +} (0..255) + +/** + * This DE indicates the type of the dangerous goods being carried by a heavy vehicle. + * The value is assigned according to `class` and `division` definitions of dangerous goods as specified in part II, + * chapter 2.1.1.1 of European Agreement concerning the International Carriage of Dangerous Goods by Road [3]. + * + * + * @category Vehicle information + * @revision: V1.3.1 + */ +DangerousGoodsBasic::= ENUMERATED { + explosives1 (0), + explosives2 (1), + explosives3 (2), + explosives4 (3), + explosives5 (4), + explosives6 (5), + flammableGases (6), + nonFlammableGases (7), + toxicGases (8), + flammableLiquids (9), + flammableSolids (10), + substancesLiableToSpontaneousCombustion (11), + substancesEmittingFlammableGasesUponContactWithWater (12), + oxidizingSubstances (13), + organicPeroxides (14), + toxicSubstances (15), + infectiousSubstances (16), + radioactiveMaterial (17), + corrosiveSubstances (18), + miscellaneousDangerousSubstances (19) +} + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `dangerousSituation` + * + * The value shall be set to: + * - 0 - `unavailable` - in case information on the type of dangerous situation is unavailable, + * - 1 - `emergencyElectronicBrakeEngaged` - in case emergency electronic brake is engaged, + * - 2 - `preCrashSystemEngaged` - in case pre-crash system is engaged, + * - 3 - `espEngaged` - in case Electronic Stability Program (ESP) system is engaged, + * - 4 - `absEngaged` - in case Anti-lock Braking System (ABS) is engaged, + * - 5 - `aebEngaged` - in case Autonomous Emergency Braking (AEB) system is engaged, + * - 6 - `brakeWarningEngaged` - in case brake warning is engaged, + * - 7 - `collisionRiskWarningEngaged` - in case collision risk warning is engaged, + * - 8-255 - reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +DangerousSituationSubCauseCode ::= INTEGER { + unavailable (0), + emergencyElectronicBrakeEngaged (1), + preCrashSystemEngaged (2), + espEngaged (3), + absEngaged (4), + aebEngaged (5), + brakeWarningEngaged (6), + collisionRiskWarningEngaged (7) +} (0..255) + +/** + * This DE represents an offset altitude with regards to a defined altitude value. + * It may be used to describe a geographical point with regards to a specific reference geographical position. + * + * The value shall be set to: + * - `-12 700` for values equal to or lower than -127 metres, + * - `n` (`n > -12 700` and `n <= 0`) for altitude offset n x 0,01 metre below the reference position, + * - `0` for no altitudinal offset, + * - `n` (`n > 0` and `n < 12799`) for altitude offset n x 0,01 metre above the reference position, + * - `12 799` for values equal to or greater than 127,99 metres, + * - `12 800` when the information is unavailable. + * + * @unit: 0,01 metre + * @category: GeoReference information + * @revision: editorial update in V2.1.1 + */ +DeltaAltitude ::= INTEGER { + negativeOutOfRange (-12700), + positiveOutOfRange (12799), + unavailable (12800) +} (-12700..12800) + +/** + * This DE represents an offset latitude with regards to a defined latitude value. + * It may be used to describe a geographical point with regards to a specific reference geographical position. + * + * The value shall be set to: + * - `n` (`n >= -131 071` and `n < 0`) for offset n x 10^-7 degree towards the south from the reference position, + * - `0` for no latitudinal offset, + * - `n` (`n > 0` and `n < 131 072`) for offset n x 10^-7 degree towards the north from the reference position, + * - `131 072` when the information is unavailable. + * + * @unit: 10^-7 degree + * @category: GeoReference information + * @revision: editorial update in V2.1.1 + */ +DeltaLatitude ::= INTEGER { + unavailable (131072) +} (-131071..131072) + +/** + * This DE represents an offset longitude with regards to a defined longitude value. + * It may be used to describe a geographical point with regards to a specific reference geographical position. + * + * The value shall be set to: + * - `n` (`n >= -131 071` and `n < 0`) for offset n x 10^-7 degree towards the west from the reference position, + * - `0` for no longitudinal offset, + * - `n` (`n > 0` and `n < 131 072`) for offset n x 10^-7 degree towards the east from the reference position, + * - `131 072` when the information is unavailable. + * + * @unit: 10^-7 degree + * @category: GeoReference information + * @revision: editorial update in V2.1.1 + */ +DeltaLongitude ::= INTEGER { + unavailable (131072) +} (-131071..131072) + +/** + * This DE represents a difference in time with respect to a reference time. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 10001`) to indicate a time value equal to or less than n x 0,001 s, and greater than (n-1) x 0,001 s, + * + * Example: a time interval between two consecutive message transmissions. + * + * @unit: 0,001 s + * @category: Basic information + * @revision: Created in V2.1.1 from the DE TransmissionInterval in [2] + */ +DeltaTimeMilliSecondPositive ::= INTEGER (1..10000) + +/** + * This DE represents a signed difference in time with respect to a reference time. + * + * The value shall be set to: + * - `-2048` for time values equal to or less than -2,048 s, + * - `n` (`n > -2048` and `n < 2047`) to indicate a time value equal to or less than n x 0,001 s, and greater than (n-1) x 0,001 s, + * - `2047` for time values greater than 2,046 s + * + * @unit: 0,001 s + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +DeltaTimeMilliSecondSigned ::= INTEGER (-2048..2047) + +/** + * This DE represents a difference in time with respect to a reference time. + * It can be interpreted as the first 8 bits of a GenerationDeltaTime. To convert it to a @ref GenerationDeltaTime, + * multiply by 256 (i.e. append a `00` byte) + * + * @unit: 256 * 0,001 s + * @category: Basic information + * @revision: Created in V2.1.1 + */ +DeltaTimeQuarterSecond::= INTEGER { + unavailable (255) +} (1..255) + +/** + * This DE represents a difference in time with respect to a reference time. + * + * The value shall be set to: + * - `0` for a difference in time of 0 seconds. + * - `n` (`n > 0` and `n < 128`) to indicate a time value equal to or less than n x 0,1 s, and greater than (n-1) x 0,1 s, + * + * @unit: 0,1 s + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +DeltaTimeTenthOfSecond::= INTEGER { + unavailable (127) +} (0..127) + +/** + * This DE represents a difference in time with respect to a reference time. + * + * The value shall be set to: + * - `-0` for a difference in time of 0 seconds. + * - `n` (`n > 0` and `n <= 86400`) to indicate a time value equal to or less than n x 1 s, and greater than (n-1) x 1 s, + * + * @unit: 1 s + * @category: Basic information + * @revision: Created in V2.1.1 from ValidityDuration +*/ +DeltaTimeSecond ::= INTEGER (0..86400) + +/** + * This DE represents a difference in time with respect to a reference time. + * + * The value shall be set to: + * - `-0` for a difference in time of 0 seconds. + * - `n` (`n > 0` and `n < 128`) to indicate a time value equal to or less than n x 10 s, and greater than (n-1) x 10 s, + * + * @unit: 10 s + * @category: Basic information + * @revision: Created in V2.2.1 +*/ +DeltaTimeTenSeconds ::= INTEGER (0..127) + +/** + * This DE indicates a direction with respect to a defined reference direction. + * Example: a reference direction may be implicitly defined by the definition of a geographical zone. + * + * The value shall be set to: + * - 0 - `sameDirection` - to indicate the same direction as the reference direction, + * - 1 - `oppositeDirection` - to indicate opposite direction as the reference direction, + * - 2 - `bothDirections` - to indicate both directions, i.e. the same and the opposite direction, + * - 3 - `unavailable` - to indicate that the information is unavailable. + * + * @category: GeoReference information + * @revision: Created in V2.1.1 + */ +Direction::= INTEGER{ + sameDirection (0), + oppositeDirection (1), + bothDirections (2), + unavailable (3) + } (0..3) + +/** + * This DE indicates in which direction something is moving. + * + * The value shall be set to: + * - 0 - `forward` - to indicate it is moving forward, + * - 1 - `backwards` - to indicate it is moving backwards, + * - 2 - `unavailable` - to indicate that the information is unavailable. + * + * @category: Kinematic information + * @revision: editorial update in V2.1.1 + */ +DriveDirection ::= ENUMERATED { + forward (0), + backward (1), + unavailable (2) +} + +/** + * This DE indicates whether a driving lane is open to traffic. + * + * A lane is counted from inside border of the road excluding the hard shoulder. The size of the bit string shall + * correspond to the total number of the driving lanes in the carriageway. + * + * The numbering is matched to @ref LanePosition. + * The bit `0` is used to indicate the innermost lane, bit `1` is used to indicate the second lane from inside border. + * + * If a lane is closed to traffic, the corresponding bit shall be set to `1`. Otherwise, it shall be set to `0`. + * + * @note: hard shoulder status is not provided by this DE but in @ref HardShoulderStatus. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +DrivingLaneStatus ::= BIT STRING (SIZE (1..13)) + +/** + * This DE indicates whether a vehicle (e.g. public transport vehicle, truck) is under the embarkation process. + * If that is the case, the value is *TRUE*, otherwise *FALSE*. + * + * @category: Vehicle information + * @revision: editorial update in V2.1.1 + */ +EmbarkationStatus ::= BOOLEAN + +/** + * This DE indicates the right of priority requested or assumed by an operating emergency vehicle. + * The right-of-priority bit shall be set to `1` if the corresponding right is requested. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 - `requestForRightOfWay` - when the vehicle is requesting/assuming the right of way, + * - 1 - `requestForFreeCrossingAtATrafficLight` - when the vehicle is requesting/assuming the right to pass at a (red) traffic light. + * + * @category: Traffic information + * @revision: description revised in V2.1.1 + */ +EmergencyPriority ::= BIT STRING { + requestForRightOfWay (0), + requestForFreeCrossingAtATrafficLight (1) +} (SIZE(2)) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode "emergencyVehicleApproaching". + * + * The value shall be set to: + * - 0 - `unavailable` - in case further detailed information on the emergency vehicle approaching event + * is unavailable, + * - 1 - `emergencyVehicleApproaching` - in case an operating emergency vehicle is approaching, + * - 2 - `prioritizedVehicleApproaching` - in case a prioritized vehicle is approaching, + * - 3-255 - reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +EmergencyVehicleApproachingSubCauseCode ::= INTEGER { + unavailable (0), + emergencyVehicleApproaching (1), + prioritizedVehicleApproaching (2) +} (0..255) + +/** + * This DE indicated the type of energy being used and stored in vehicle. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 - `hydrogenStorage` - when hydrogen is being used and stored in vehicle, + * - 1 - `electricEnergyStorage` - when electric energy is being used and stored in vehicle, + * - 2 - `liquidPropaneGas` - when liquid Propane Gas (LPG) is being used and stored in vehicle, + * - 3 - `compressedNaturalGas ` - when compressedNaturalGas (CNG) is being used and stored in vehicle, + * - 4 - `diesel` - when diesel is being used and stored in vehicle, + * - 5 - `gasoline` - when gasoline is being used and stored in vehicle, + * - 6 - `ammonia` - when ammonia is being used and stored in vehicle. + * + * - Otherwise, the corresponding bit shall be set to `0`. + * + * @category: Vehicle information + * @revision: editorial revision in V2.1.1 + */ +EnergyStorageType ::= BIT STRING { + hydrogenStorage (0), + electricEnergyStorage (1), + liquidPropaneGas (2), + compressedNaturalGas (3), + diesel (4), + gasoline (5), + ammonia (6) +}(SIZE(7)) + +/** + * This DE represents one of the specific categories in the L category: L1, L2, L3, L4, L5, L6, or L7 according to UNECE/TRANS/WP.29/78/Rev.4 [16]. + * + * + * @category: Vehicle information + * @revision: V2.1.1 + */ +EuVehicleCategoryL ::= ENUMERATED { l1, l2, l3, l4, l5, l6, l7 } + +/** + * This DE represents one of the specific categories in the M category: M1, M2, or M3 according to UNECE/TRANS/WP.29/78/Rev.4 [16]. + * + * + * @category: Vehicle information + * @revision: V2.1.1 + */ +EuVehicleCategoryM ::= ENUMERATED {m1, m2, m3} + +/** + * This DE represents one of the specific categories in the N category: N1, N2, or N3 according to UNECE/TRANS/WP.29/78/Rev.4 [16]. + * + * + * @category: Vehicle information + * @revision: V2.1.1 + */ +EuVehicleCategoryN ::= ENUMERATED {n1, n2, n3} + +/** + * This DE represents one of the specific categories in the O category: O1, O2, O3 or O4 according to UNECE/TRANS/WP.29/78/Rev.4 [16]. + * + * + * @category: Vehicle information + * @revision: V2.1.1 + */ +EuVehicleCategoryO ::= ENUMERATED {o1, o2, o3, o4} + +/** + * This DE describes the status of the exterior light switches of a vehicle incl. VRU vehicles. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 - `lowBeamHeadlightsOn` - when the low beam head light switch is on, + * - 1 - `highBeamHeadlightsOn` - when the high beam head light switch is on, + * - 2 - `leftTurnSignalOn` - when the left turnSignal switch is on, + * - 3 - `rightTurnSignalOn` - when the right turn signal switch is on, + * - 4 - `daytimeRunningLightsOn` - when the daytime running light switch is on, + * - 5 - `reverseLightOn` - when the reverse light switch is on, + * - 6 - `fogLightOn` - when the tail fog light switch is on, + * - 7 - `parkingLightsOn` - when the parking light switch is on. + * + * @note: The value of each bit indicates the state of the switch, which commands the corresponding light. + * The bit corresponding to a specific light is set to `1`, when the corresponding switch is turned on, + * either manually by the driver or automatically by a vehicle system. The bit value does not indicate + * if the corresponding lamps are alight or not. + * + * If a vehicle is not equipped with a certain light or if the light switch status information is not available, + * the corresponding bit shall be set to `0`. + * + * As the bit value indicates only the state of the switch, the turn signal and hazard signal bit values shall not + * alternate with the blinking interval. + * + * For hazard indicator, the `leftTurnSignalOn (2)` and `rightTurnSignalOn (3)` shall be both set to `1`. + * + * @category Vehicle information + * @revision: Description revised in V2.1.1 + */ +ExteriorLights ::= BIT STRING { + lowBeamHeadlightsOn (0), + highBeamHeadlightsOn (1), + leftTurnSignalOn (2), + rightTurnSignalOn (3), + daytimeRunningLightsOn (4), + reverseLightOn (5), + fogLightOn (6), + parkingLightsOn (7) +} (SIZE(8)) + +/** + * This DE represents a timestamp based on TimestampIts modulo 65 536. + * This means that generationDeltaTime = TimestampIts mod 65 536. + * + * @category: Basic information + * @revision: Created in V2.1.1 based on ETSI TS 103 900 [1] +*/ +GenerationDeltaTime ::= INTEGER { oneMilliSec(1) } (0..65535) + +/** + * This DE indicates the current status of a hard shoulder: whether it is available for special usage + * (e.g. for stopping or for driving) or closed for all vehicles. + * + * The value shall be set to: + * - 0 - `availableForStopping` - if the hard shoulder is available for stopping in e.g. emergency situations, + * - 1 - `closed` - if the hard shoulder is closed and cannot be occupied in any case, + * - 2 - `availableForDriving` - if the hard shoulder is available for regular driving. + * + * @category: Traffic information + * @revision: Description revised in V2.1.1 + */ +HardShoulderStatus ::= ENUMERATED { + availableForStopping (0), + closed (1), + availableForDriving (2) +} + +/** + * This DE represents the value of the sub cause code of the @ref CauseCode `hazardousLocation-AnimalOnTheRoad`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case further detailed information on the animal(s) on the road is unavailable, + * - 1 - `wildAnimals` - in case wild animals of unknown size are present on the road, + * - 2 - `herdOfAnimals` - in case a herd of animals is present on the road, + * - 3 - `smallAnimals` - in case small size animals of unknown type are present on the road, + * - 4 - `largeAnimals` - in case large size animals of unknown type are present on the road, + * - 5 - `wildAnimalsSmall` - in case small size wild animal(s) are present on the road, + * - 6 - `wildAnimalsLarge` - in case large size wild animal(s) are present on the road, + * - 7 - `domesticAnimals` - in case domestic animal(s) of unknown size are detected on the road, + * - 8 - `domesticAnimalsSmall` - in case small size domestic animal(s) are present on the road, + * - 9 - `domesticAnimalsLarge` - in case large size domestic animal(s) are present on the road. + * - 10-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1, named values 5 to 9 added in V2.2.1 + */ +HazardousLocation-AnimalOnTheRoadSubCauseCode ::= INTEGER { + unavailable (0), + wildAnimals (1), + herdOfAnimals (2), + smallAnimals (3), + largeAnimals (4), + wildAnimalsSmall (5), + wildAnimalsLarge (6), + domesticAnimals (7), + domesticAnimalsSmall (8), + domesticAnimalsLarge (9) +} (0..255) + +/** + * This DE represents the sub cause code of the @ref CauseCode `hazardousLocation-DangerousCurve`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case further detailed information on the dangerous curve is unavailable, + * - 1 - `dangerousLeftTurnCurve` - in case the dangerous curve is a left turn curve, + * - 2 - `dangerousRightTurnCurve` - in case the dangerous curve is a right turn curve, + * - 3 - `multipleCurvesStartingWithUnknownTurningDirection` - in case of multiple curves for which the starting curve turning direction is not known, + * - 4 - `multipleCurvesStartingWithLeftTurn` - in case of multiple curves starting with a left turn curve, + * - 5 - `multipleCurvesStartingWithRightTurn` - in case of multiple curves starting with a right turn curve. + * - 6-255 - are reserved for future usage. + * + * The definition of whether a curve is dangerous may vary according to region and according to vehicle types/mass + * and vehicle speed driving on the curve. This definition is out of scope of the present document. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +HazardousLocation-DangerousCurveSubCauseCode ::= INTEGER { + unavailable (0), + dangerousLeftTurnCurve (1), + dangerousRightTurnCurve (2), + multipleCurvesStartingWithUnknownTurningDirection (3), + multipleCurvesStartingWithLeftTurn (4), + multipleCurvesStartingWithRightTurn (5) +} (0..255) + +/** + * This DE represents the value of the sub cause code of the @ref CauseCode `hazardousLocation-ObstacleOnTheRoad`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case further detailed information on the detected obstacle is unavailable, + * - 1 - `shedLoad` - in case detected obstacle is large amount of obstacles (shedload), + * - 2 - `partsOfVehicles`- in case detected obstacles are parts of vehicles, + * - 3 - `partsOfTyres` - in case the detected obstacles are parts of tyres, + * - 4 - `bigObjects` - in case the detected obstacles are big objects, + * - 5 - `fallenTrees` - in case the detected obstacles are fallen trees, + * - 6 - `hubCaps` - in case the detected obstacles are hub caps, + * - 7 - `waitingVehicles`- in case the detected obstacles are waiting vehicles. + * - 8-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +HazardousLocation-ObstacleOnTheRoadSubCauseCode ::= INTEGER { + unavailable (0), + shedLoad (1), + partsOfVehicles (2), + partsOfTyres (3), + bigObjects (4), + fallenTrees (5), + hubCaps (6), + waitingVehicles (7) +} (0..255) + +/** + * This DE represents the value of the sub cause code of the @ref CauseCode `hazardousLocation-SurfaceCondition`. + * +The value shall be set to: + * - 0 - `unavailable` - in case further detailed information on the road surface condition is unavailable, + * - 1 - `rockfalls` - in case rock falls are detected on the road surface, + * - 2 - `earthquakeDamage`- in case the road surface is damaged by earthquake, + * - 3 - `sewerCollapse` - in case of sewer collapse on the road surface, + * - 4 - `subsidence` - in case road surface is damaged by subsidence, + * - 5 - `snowDrifts` - in case road surface is damaged due to snow drift, + * - 6 - `stormDamage` - in case road surface is damaged by strong storm, + * - 7 - `burstPipe` - in case road surface is damaged due to pipe burst, + * - 8 - `volcanoEruption` - in case road surface is damaged due to volcano eruption, + * - 9 - `fallingIce` - in case road surface damage is due to falling ice, + * - 10 - `fire` - in case there is fire on or near to the road surface, + * - 11 - `flooding` - in case the road surface is flooded. + * - 12-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1, value 11 added in V2.3.1 + */ +HazardousLocation-SurfaceConditionSubCauseCode ::= INTEGER { + unavailable (0), + rockfalls (1), + earthquakeDamage (2), + sewerCollapse (3), + subsidence (4), + snowDrifts (5), + stormDamage (6), + burstPipe (7), + volcanoEruption (8), + fallingIce (9), + fire (10), + flooding (11) +} (0..255) + +/** + * This DE indicates the heading confidence value which represents the estimated absolute accuracy of a heading value with a confidence level of 95 %. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 126`) if the confidence value is equal to or less than n x 0,1 degree and more than (n-1) x 0,1 degree, + * - `126` if the confidence value is out of range, i.e. greater than 12,5 degrees, + * - `127` if the confidence value information is not available. + * + * @note: The fact that a value is received with confidence value set to `unavailable(127)` can be caused by several reasons, + * such as: + * - the sensor cannot deliver the accuracy at the defined confidence level because it is a low-end sensor, + * - the sensor cannot calculate the accuracy due to lack of variables, or + * - there has been a vehicle bus (e.g. CAN bus) error. + * In all 3 cases above, the heading value may be valid and used by the application. + * + * @note: If a heading value is received and its confidence value is set to `outOfRange(126)`, it means that the + * heading value is not valid and therefore cannot be trusted. Such value is not useful for the application. + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref Wgs84AngleConfidence instead. + * + * @unit: 0,1 degree + * @category: GeoReference information + * @revision: Description revised in V2.1.1 + */ +HeadingConfidence ::= INTEGER { + outOfRange (126), + unavailable (127) +} (1..127) + +/** + * This DE represents the orientation of the horizontal velocity vector with regards to the WGS84 north. + * When the information is not available, the DE shall be set to 3 601. The value 3600 shall not be used. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref Wgs84AngleValue instead. + * + * Unit: 0,1 degree + * Categories: GeoReference information + * @revision: Description revised in V2.1.1 (usage of value 3600 specified) +*/ +HeadingValue ::= INTEGER { + wgs84North (0), + wgs84East (900), + wgs84South (1800), + wgs84West (2700), + doNotUse (3600), + unavailable (3601) +} (0..3601) + +/** + * This DE represents the height of the left or right longitude carrier of vehicle from base to top (left or right carrier seen from vehicle + * rear to front). + * + * The value shall be set to: + * - `n` (`n >= 1` and `n < 99`) if the height information is equal to or less than n x 0,01 metre and more than (n-1) x 0,01 metre, + * - `99` if the height is out of range, i.e. equal to or greater than 0,98 m, + * - `100` if the height information is not available. + * + * @unit 0,01 metre + * @category Vehicle information + * @revision: Description revised in V2.1.1 (the definition of 99 has changed slightly) + */ +HeightLonCarr ::= INTEGER { + outOfRange(99), + unavailable(100) +} (1..100) + +/** + * This DE represents the value of the sub cause code of the @ref CauseCode `humanPresenceOnTheRoad`. + * + * The value shall be set to: + * - 0 - `unavailable` - in case further detailed information abou the human presence on the road is unavailable, + * - 1 - `childrenOnRoadway` - in case children are present on the road, + * - 2 - `cyclistOnRoadway` - in case cyclist(s) are present on the road, + * - 3 - `motorcyclistOnRoadway` - in case motorcyclist(s) are present on the road, + * - 4 - `pedestrian` - in case pedestrian(s) of any type are present on the road, + * - 5 - `ordinary-pedestrian` - in case pedestrian(s) to which no more-specific profile applies are present on the road, + * - 6 - `road-worker` - in case pedestrian(s) with the role of a road worker applies are present on the road, + * - 7 - `first-responder` - in case pedestrian(s) with the role of a first responder applies are present on the road, + * - 8 - `lightVruVehicle - in case light vru vehicle(s) of any type are present on the road, + * - 9 - `bicyclist ` - in case cycle(s) and their bicyclist(s) are present on the road, + * - 10 - `wheelchair-user` - in case wheelchair(s) and their user(s) are present on the road, + * - 11 - `horse-and-rider` - in case horse(s) and rider(s) are present on the road, + * - 12 - `rollerskater` - in case rolleskater(s) and skater(s) are present on the road, + * - 13 - `e-scooter` - in case e-scooter(s) and rider(s) are present on the road, + * - 14 - `personal-transporter` - in case personal-transporter(s) and rider(s) are present on the road, + * - 15 - `pedelec` - in case pedelec(s) and rider(s) are present on the road, + * - 16 - `speed-pedelec` - in case speed-pedelec(s) and rider(s) are present on the road, + * - 17 - `ptw` - in case powered-two-wheeler(s) of any type are present on the road, + * - 18 - `moped` - in case moped(s) and rider(s) are present on the road, + * - 19 - `motorcycle` - in case motorcycle(s) and rider(s) are present on the road, + * - 20 - `motorcycle-and-sidecar-right` - in case motorcycle(s) with sidecar(s) on the right and rider are present on the road, + * - 21 - `motorcycle-and-sidecar-left` - in case motorcycle(s) with sidecar(s) on the left and rider are present on the road. + * - 22-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: editorial revision in V2.1.1, named values 4-21 added in V2.2.1 + */ +HumanPresenceOnTheRoadSubCauseCode ::= INTEGER { + unavailable (0), + childrenOnRoadway (1), + cyclistOnRoadway (2), + motorcyclistOnRoadway (3), + pedestrian (4), + ordinary-pedestrian (5), + road-worker (6), + first-responder (7), + lightVruVehicle (8), + bicyclist (9), + wheelchair-user (10), + horse-and-rider (11), + rollerskater (12), + e-scooter (13), + personal-transporter (14), + pedelec (15), + speed-pedelec (16), + ptw (17), + moped (18), + motorcycle (19), + motorcycle-and-sidecar-right (20), + motorcycle-and-sidecar-left (21) +} (0..255) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode "humanProblem". + * + * The value shall be set to: + * - 0 - `unavailable` - in case further detailed information on human health problem is unavailable, + * - 1 - `glycemiaProblem`- in case human problem is due to glycaemia problem, + * - 2 - `heartProblem` - in case human problem is due to heart problem. + * - 3-255 - reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +HumanProblemSubCauseCode ::= INTEGER { + unavailable (0), + glycemiaProblem (1), + heartProblem (2) +} (0..255) + +/** + * This DE is a general identifier. + * + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +Identifier1B ::= INTEGER (0..255) + +/** + * This DE is a general identifier. + * + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +Identifier2B ::= INTEGER (0..65535) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `impassability` + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information about the unmanaged road blockage is unavailable, + * - 1 `flooding ` - in case the road is affected by flooding, + * - 2 `dangerOfAvalanches` - in case the road is at risk of being affected or blocked by avalanches, + * - 3 `blastingOfAvalanches` - in case there is an active blasting of avalanches on or near the road, + * - 4 `landslips` - in case the road is affected by landslips, + * - 5 `chemicalSpillage` - in case the road is affected by chemical spillage, + * - 6 `winterClosure` - in case the road is impassable due to a winter closure. + * - 7 `sinkhole` - in case the road is impassable due to large holes in the road surface. + * - 8 `earthquakeDamage` - in case the road is obstructed or partially obstructed because of damage caused by an earthquake. + * - 9 `fallenTrees` - in case the road is obstructed or partially obstructed by one or more fallen trees. + * - 10 `rockfalls` - in case the road is obstructed or partially obstructed due to fallen rocks. + * - 11 `sewerOverflow` - in case the road is obstructed or partially obstructed by overflows from one or more sewers. + * - 12 `stormDamage` - in case the road is obstructed or partially obstructed by debris caused by strong winds. + * - 13 `subsidence` - in case the road surface has sunken or collapsed in places. + * - 14 `burstPipe` - in case the road surface has sunken or collapsed in places due to burst pipes. + * - 15 `burstWaterMain` - in case the road is obstructed due to local flooding and/or subsidence. + * - 16 `fallenPowerCables` - in case the road is obstructed or partly obstructed by one or more fallen power cables. + * - 17 `snowDrifts` - in case the road is obstructed or partially obstructed by snow drifting in progress or patches of deep snow due to earlier drifting. + * - 15-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: Created in V2.2.1 +*/ +ImpassabilitySubCauseCode ::= INTEGER { + unavailable (0), + flooding (1), + dangerOfAvalanches (2), + blastingOfAvalanches (3), + landslips (4), + chemicalSpillage (5), + winterClosure (6), + sinkhole (7), + earthquakeDamage (8), + fallenTrees (9), + rockfalls (10), + sewerOverflow (11), + stormDamage (12), + subsidence (13), + burstPipe (14), + burstWaterMain (15), + fallenPowerCables (16), + snowDrifts (17) +} (0..255) + +/** + * This DE represents the quality level of provided information. + * + * The value shall be set to: + * - `0` if the information is unavailable, + * - `1` if the quality level is lowest, + * - `n` (`n > 1` and `n < 7`) if the quality level is n, + * - `7` if the quality level is highest. + * + * @note: Definition of quality level is out of scope of the present document. + * @category: Basic information + * @revision: Editorial update in V2.1.1 + */ +InformationQuality ::= INTEGER (0..7) + +/** + * This DE defines the type of an interference management zone, so that an ITS-S can + * assert the actions to do while passing by such zone (e.g. reduce the transmit power in case of a DSRC tolling station). + * It is an extension of the type @ref ProtectedZoneType. + * + * The value shall be set to: + * - 0 - `permanentCenDsrcTolling` - as specified in ETSI TS 102 792 [14], + * - 1 - `temporaryCenDsrcTolling` - as specified in ETSI TS 102 792 [14], + * - 2 - `unavailable` - default value. Set to 2 for backwards compatibility with DSRC tolling, + * - 3 - `urbanRail` - as specified in ETSI TS 103 724 [13], clause 7, + * - 4 - `satelliteStation` - as specified in ETSI TS 103 724 [13], clause 7, + * - 5 - `fixedLinks` - as specified in ETSI TS 103 724 [13], clause 7. + * + * @category: Communication information + * @revision: Created in V2.1.1 + */ +InterferenceManagementZoneType ::= ENUMERATED { + permanentCenDsrcTolling (0), + temporaryCenDsrcTolling (1), + unavailable (2), + urbanRail (3), + satelliteStation (4), + fixedLinks (5), + ... +} + +/** + * This DE represents the vehicle type according to ISO 3833 [22]. + * A "term No" refers to the number of the corresponding term and its definition in ISO 3833. + * + * The value shall be set to: + * - 0 - `passengerCar` - term No 3.1.1 + * - 1 - `saloon` - term No 3.1.1.1 (sedan) + * - 2 - `convertibleSaloon` - term No 3.1.1.2 + * - 3 - `pullmanSaloon` - term No 3.1.1.3 + * - 4 - `stationWagon` - term No 3.1.1.4 + * - 5 - `truckStationWagon` - term No 3.1.1.4.1 + * - 6 - `coupe` - term No 3.1.1.5 (coupe) + * - 7 - `convertible` - term No 3.1.1.6 (open tourer, roadstar, spider) + * - 8 - `multipurposePassengerCar` - term No 3.1.1.7 + * - 9 - `forwardControlPassengerCar`- term No 3.1.1.8 + * - 10 - `specialPassengerCar` - term No 3.1.1.9 + * - 11 - `bus` - term No 3.1.2 + * - 12 - `minibus` - term No 3.1.2.1 + * - 13 - `urbanBus` - term No 3.1.2.2 + * - 14 - `interurbanCoach` - term No 3.1.2.3 + * - 15 - `longDistanceCoach` - term No 3.1.2.4 + * - 16 - `articulatedBus` - term No 3.1.2.5 + * - 17 - `trolleyBus ` - term No 3.1.2.6 + * - 18 - `specialBus` - term No 3.1.2.7 + * - 19 - `commercialVehicle` - term No 3.1.3 + * - 20 - `specialCommercialVehicle` - term No 3.1.3.1 + * - 21 - `specialVehicle` - term No 3.1.4 + * - 22 - `trailingTowingVehicle` - term No 3.1.5 (draw-bar tractor) + * - 23 - `semiTrailerTowingVehicle` - term No 3.1.6 (fifth wheel tractor) + * - 24 - `trailer` - term No 3.2.1 + * - 25 - `busTrailer` - term No 3.2.1.1 + * - 26 - `generalPurposeTrailer` - term No 3.2.1.2 + * - 27 - `caravan` - term No 3.2.1.3 + * - 28 - `specialTrailer` - term No 3.2.1.4 + * - 29 - `semiTrailer` - term No 3.2.2 + * - 30 - `busSemiTrailer` - term No 3.2.2.1 + * - 31 - `generalPurposeSemiTrailer` - term No 3.2.2.2 + * - 32 - `specialSemiTrailer` - term No 3.2.2.3 + * - 33 - `roadTrain` - term No 3.3.1 + * - 34 - `passengerRoadTrain` - term No 3.3.2 + * - 35 - `articulatedRoadTrain` - term No 3.3.3 + * - 36 - `doubleRoadTrain` - term No 3.3.4 + * - 37 - `compositeRoadTrain` - term No 3.3.5 + * - 38 - `specialRoadTrain` - term No 3.3.6 + * - 39 - `moped` - term No 3.4 + * - 40 - `motorCycle` - term No 3.5 + * - 41-255 - reserved for future use + * + * @category: Vehicle information + * @revision: Created in V2.1.1 + */ +Iso3833VehicleType ::= INTEGER { + passengerCar (0), + saloon (1), + convertibleSaloon (2), + pullmanSaloon (3), + stationWagon (4), + truckStationWagon (5), + coupe (6), + convertible (7), + multipurposePassengerCar (8), + forwardControlPassengerCar (9), + specialPassengerCar (10), + bus (11), + minibus (12), + urbanBus (13), + interurbanCoach (14), + longDistanceCoach (15), + articulatedBus (16), + trolleyBus (17), + specialBus (18), + commercialVehicle (19), + specialCommercialVehicle (20), + specialVehicle (21), + trailingTowingVehicle (22), + semiTrailerTowingVehicle (23), + trailer (24), + busTrailer (25), + generalPurposeTrailer (26), + caravan (27), + specialTrailer (28), + semiTrailer (29), + busSemiTrailer (30), + generalPurposeSemiTrailer (31), + specialSemiTrailer (32), + roadTrain (33), + passengerRoadTrain (34), + articulatedRoadTrain (35), + doubleRoadTrain (36), + compositeRoadTrain (37), + specialRoadTrain (38), + moped (39), + motorCycle (40) + } (0..255) + +/** + * This DE represent the identifier of an organization according to the applicable registry. + * + * @category: Basic information + * @revision: Created in V2.2.1 based on ISO 14816 [23] +*/ +IssuerIdentifier ::= INTEGER(0 .. 16383) + +/** + * This DE represents the identifier of the IVIM. + * + * @category: Basic information + * @revision: Created in V2.2.1 based on ETSI TS 103 301 [15] +*/ +IviIdentificationNumber::= INTEGER(1..32767,..., 8388607) + +/** + * This DE indicates a transversal position on the carriageway at a specific longitudinal position, in resolution of lanes of the carriageway. + * + * For right-hand traffic roads, the value shall be set to: + * - `-1` if the position is off, i.e. besides the road, + * - `0` if the position is on the inner hard shoulder, i.e. the hard should adjacent to the leftmost lane, + * - `n` (`n > 0` and `n < 14`), if the position is on the n-th driving lane counted from the leftmost lane to the rightmost lane of a specific traffic direction, + * - `14` if the position is on the outer hard shoulder, i.e. the hard should adjacent to rightmost lane (if present). + * + * For left-hand traffic roads, the value shall be set to: + * - `-1` if the position is off, i.e. besides the road, + * - `0` if the position is on the inner hard shoulder, i.e. the hard should adjacent to the rightmost lane, + * - `n` (`n > 0` and `n < 14`), if the position is on the n-th driving lane counted from the rightmost lane to the leftmost lane of a specific traffic direction, + * - `14` if the position is on the outer hard shoulder, i.e. the hard should adjacent to leftmost lane (if present). + * + * @note: in practice this means that the position is counted from "inside" to "outside" no matter which traffic practice is used. + * + * If the carriageway allows only traffic in one direction (e.g. in case of dual or multiple carriageway roads), the position is counted from the physical border of the carriageway. + * If the carriageway allows traffic in both directions and there is no physical delimitation between traffic directions (e.g. on a single carrriageway road), + * the position is counted from the legal (i.e. optical) separation between traffic directions (horizontal marking). + * + * If not indicated otherwise (by lane markings or traffic signs), the legal separation on carriageways allowing traffic on both directions is identified as follows: + * - If the total number of lanes N is even, the lanes are divided evenly between the traffic directions starting from the outside of the carriageway on both sides and the + * imaginary separation between traffic directions is on the border between the even number of lanes N/2. + * - If the total number of lanes N is odd, the lanes are divided evenly between traffic direction starting from the outside of the carriageway on both sides. + * The remaining middle lane is assigned to both traffic directions as innermost lane. + * + * @category: Road topology information + * @revision: Description of the legal separation of carriageways added in V2.2.1 +*/ +LanePosition ::= INTEGER { + offTheRoad (-1), + innerHardShoulder (0), + outerHardShoulder (14) +} (-1..14) + +/** + * This DE represents the type of a lane. + * + * The value shall be set to: + * - 0 - `traffic` - Lane dedicated to the movement of vehicles, + * - 1 - `through` - Lane dedicated to the movement of vehicles travelling ahead and not turning, + * - 2 - `reversible` - Lane where the direction of traffic can be changed to match the peak flow, + * - 3 - `acceleration` - Lane that allows vehicles entering a road to accelerate to the speed of through traffic before merging with it, + * - 4 - `deceleration` - Lane that allows vehicles exiting a road to decelerate before leaving it, + * - 5 - `leftHandTurning` - Lane reserved for slowing down and making a left turn, so as not to disrupt traffic, + * - 6 - `rightHandTurning` - Lane reserved for slowing down and making a right turn so as not to disrupt traffic, + * - 7 - `dedicatedVehicle` - Lane dedicated to movement of motor vehicles with specific characteristics, such as heavy goods vehicles, etc., + * - 8 - `bus` - Lane dedicated to movement of buses providing public transport, + * - 9 - `taxi` - Lane dedicated to movement of taxis, + * - 10 - `hov` - Carpooling lane or high occupancy vehicle lane, + * - 11 - `hot` - High occupancy vehicle lanes that is allowed to be used without meeting the occupancy criteria by paying a toll, + * - 12 - `pedestrian` - Lanes dedicated to pedestrians such as pedestrian sidewalk paths, + * - 13 - `cycleLane` - Lane dedicated to exclusive or preferred use by bicycles, + * - 14 - `median` - Lane not dedicated to movement of vehicles but representing a median / central reservation such as the central median, + separating the two directional carriageways of the highway, + * - 15 - `striping` - Lane not dedicated to movement of vehicles but covered with roadway markings, + * - 16 - `trackedVehicle` - Lane dedicated to movement of trains, trams and trolleys, + * - 17 - `parking` - Lanes dedicated to vehicles parking, stopping and loading lanes, + * - 18 - `emergency` - Lane dedicated to vehicles in breakdown or to emergency vehicles also called hard shoulder, + * - 19 - `verge` - Lane representing the verge, i.e. a narrow strip of grass or plants and sometimes also trees located between + the road surface edge and the boundary of a road, + * - 20 `minimumRiskManoeuvre` - Lane dedicated to automated vehicles making a minimum risk manoeuvre, + * - 21 `separatedCycleLane` - Lane dedicated to exclusive or preferred use by bicycles that is phyisically separated from the vehicle-traffic lanes, e.g. by a verge. + * - values 22 to 30 reserved for future use. + * + * @category: Road topology information + * @revision: Created in V2.1.1, named value 21 added in V2.2.1 +*/ +LaneType::= INTEGER{ + traffic (0), + through (1), + reversible (2), + acceleration (3), + deceleration (4), + leftHandTurning (5), + rightHandTurning (6), + dedicatedVehicle (7), + bus (8), + taxi (9), + hov (10), + hot (11), + pedestrian (12), + cycleLane (13), + median (14), + striping (15), + trackedVehicle (16), + parking (17), + emergency (18), + verge (19), + minimumRiskManoeuvre (20), + exclusiveCycleLane (21), + unknown (31) +}(0..31) + +/** + * This DE represents the width of a lane measured at a defined position. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 1022`) if the lane width information is equal to or less than n x 0,01 metre and more than (n-1) x 0,01 metre, + * - `1022` if the lane width is out of range, i.e. greater than 10,21 m, + * - `1023` if the lane width information is not available. + * + * The value 0 shall not be used. + * + * @unit: 0,01 metre + * @category: Road topology information + * @revision: Created in V2.1.1 + */ +LaneWidth::= INTEGER (0..1023) + +/** + * This DE represents the absolute geographical latitude in a WGS84 coordinate system, providing a range of 90 degrees in north or + * in south hemisphere. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n >= -900 000 000` and `n < 0`) x 10^-7 degree, i.e. negative values for latitudes south of the Equator, + * - `0` is used for the latitude of the equator, + * - `n` (`n > 0` and `n < 900 000 001`) x 10^-7 degree, i.e. positive values for latitudes north of the Equator, + * - `900 000 001` when the information is unavailable. + * + * @unit: 10^-7 degree + * @category: GeoReference information + * @revision: Editorial update in V2.1.1 + */ +Latitude ::= INTEGER { + unavailable(900000001) +} (-900000000..900000001) + +/** + * This DE represents the vehicle acceleration at lateral direction in the centre of the mass of the empty vehicle. + * It corresponds to the vehicle coordinate system as specified in ISO 8855 [21]. + * + * The value shall be set to: + * - `-160` for acceleration values equal to or less than -16 m/s^2, + * - `n` (`n > -160` and `n <= 0`) to indicate that the vehicle is accelerating towards the right side with regards to the vehicle orientation + * with acceleration equal to or less than n x 0,1 m/s^2 and greater than (n-1) x 0,1 m/s^2, + * - `n` (`n > 0` and `n < 160`) to indicate that the vehicle is accelerating towards the left hand side with regards to the vehicle orientation + with acceleration equal to or less than n x 0,1 m/s^2 and greater than (n-1) x 0,1 m/s^2, + * - `160` for acceleration values greater than 15,9 m/s^2, + * - `161` when the data is unavailable. + * + * @note: the empty load vehicle is defined in ISO 1176 [8], clause 4.6. + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use @ref AccelerationValue instead. + * + * @unit: 0,1 m/s^2 + * @category: Vehicle information + * @revision: Description updated in V2.1.1 (the meaning of 160 has changed slightly). + */ +LateralAccelerationValue ::= INTEGER { + negativeOutOfRange (-160), + positiveOutOfRange (160), + unavailable (161) +} (-160 .. 161) + +/** + * This DE indicates the status of light bar and any sort of audible alarm system besides the horn. + * This includes various common sirens as well as backup up beepers and other slow speed manoeuvring alerts. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 - `lightBarActivated` - when the light bar is activated, + * - 1 - `sirenActivated` - when the siren is activated. + * + * Otherwise, it shall be set to 0. + * + * @category Vehicle information + * @revision: Editorial update in V2.1.1 + */ +LightBarSirenInUse ::= BIT STRING { + lightBarActivated (0), + sirenActivated (1) +} (SIZE(2)) + +/** + * This DE represents the absolute geographical longitude in a WGS84 coordinate system, providing a range of 180 degrees + * to the east or to the west of the prime meridian. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n > -1 800 000 000` and `n < 0`) x 10^-7 degree, i.e. negative values for longitudes to the west, + * - `0` to indicate the prime meridian, + * - `n` (`n > 0` and `n < 1 800 000 001`) x 10^-7 degree, i.e. positive values for longitudes to the east, + * - `1 800 000 001` when the information is unavailable. + * + * The value -1 800 000 000 shall not be used. + * + * @unit: 10^-7 degree + * @category: GeoReference information + * @revision: Description revised in V2.1.1 + */ +Longitude ::= INTEGER { + valueNotUsed (-1800000000), + unavailable (1800000001) +} (-1800000000..1800000001) + + /** + * This DE represents the vehicle acceleration at longitudinal direction in the centre of the mass of the empty vehicle. + * The value shall be provided in the vehicle coordinate system as defined in ISO 8855 [21], clause 2.11. + * + * The value shall be set to: + * - `-160` for acceleration values equal to or less than -16 m/s^2, + * - `n` (`n > -160` and `n <= 0`) to indicate that the vehicle is braking with acceleration equal to or less than n x 0,1 m/s^2, and greater than (n-1) x 0,1 m/s^2 + * - `n` (`n > 0` and `n < 160`) to indicate that the vehicle is accelerating with acceleration equal to or less than n x 0,1 m/s^2, and greater than (n-1) x 0,1 m/s^2, + * - `160` for acceleration values greater than 15,9 m/s^2, + * - `161` when the data is unavailable. + * + * This acceleration is along the tangent plane of the road surface and does not include gravity components. + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use @ref AccelerationValue instead. + * + * @note: The empty load vehicle is defined in ISO 1176 [8], clause 4.6. + * @unit: 0,1 m/s^2 + * @category: Vehicle information + * @revision: description revised in V2.1.1 (the meaning of 160 has changed slightly). T + */ +LongitudinalAccelerationValue::= INTEGER { + negativeOutOfRange (-160), + positiveOutOfRange (160), + unavailable (161) +} (-160 .. 161) + +/** + * This DE represents the longitudinal offset of a map-matched position along a matched lane, beginning from the lane's starting point. + * + * The value shall be set to: + * - `n` (`n >= 0` and `n < 32766`) if the longitudinal offset information is equal to or less than n x 0,1 metre and more than (n-1) x 0,1 metre, + * - `32 766` if the longitudinal offset is out of range, i.e. greater than 3276,5 m, + * - `32 767` if the longitudinal offset information is not available. + * + * @unit 0,1 metre + * @category: GeoReference information + * @revision: Created in V2.1.1 +*/ +LongitudinalLanePositionValue ::= INTEGER { + outOfRange(32766), + unavailable(32767) +}(0..32767) + +/** + * This DE indicates the longitudinal lane position confidence value which represents the estimated accuracy of longitudinal lane position measurement with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 1 022`) if the confidence value is equal to or less than n x 0,1 m, and more than (n-1) x 0,1 m, + * - `1 022` if the confidence value is out of range i.e. greater than 102,1 m, + * - `1 023` if the confidence value is unavailable. + * + * @unit 0,1 metre + * @category: GeoReference information + * @revision: Created in V2.1.1 +*/ +LongitudinalLanePositionConfidence ::= INTEGER { + outOfRange (1022), + unavailable (1023) +} (0..1023) + +/** + * This DE indicates the components of an @ref PerceivedObject that are included in the @ref LowerTriangularPositiveSemidefiniteMatrix. + * + * The corresponding bit shall be set to 1 if the component is included: + * - 0 - `xCoordinate` - when the component xCoordinate of the component @ref CartesianPosition3dWithConfidence is included, + * - 1 - `yCoordinate` - when the component yCoordinate of the component @ref CartesianPosition3dWithConfidence is included, + * - 2 - `zCoordinate` - when the component zCoordinate of the component @ref CartesianPosition3dWithConfidence is included, + * - 3 - `xVelocityOrVelocityMagnitude` - when the component xVelocity of the component @ref VelocityCartesian or the component VelocityMagnitude of the component @ref VelocityPolarWithZ is included, + * - 4 - `yVelocityOrVelocityDirection` - when the component yVelocity of the component @ref VelocityCartesian or the component VelocityDirection of the component @ref VelocityPolarWithZ is included, + * - 5 - `zVelocity` - when the component zVelocity of the component @ref VelocityCartesian or of the component @ref VelocityPolarWithZ is included, + * - 6 - `xAccelOrAccelMagnitude` - when the component xAcceleration of the component @ref AccelerationCartesian or the component AccelerationMagnitude of the component @ref AccelerationPolarWithZ is included, + * - 7 - `yAccelOrAccelDirection` - when the component yAcceleration of the component @ref AccelerationCartesian or the component AccelerationDirection of the component @ref AccelerationPolarWithZ is included, + * - 8 - `zAcceleration` - when the component zAcceleration of the component @ref AccelerationCartesian or of the component @ref AccelerationPolarWithZ is included, + * - 9 - `zAngle` - when the component zAngle is included, + * - 10 - `yAngle` - when the component yAngle is included, + * - 11 - `xAngle` - when the component xAngle is included, + * - 12 - `zAngularVelocity` - when the component zAngularVelocity is included. + * + * Otherwise, it shall be set to 0. + * + * @category: Sensing information + * @revision: Created in V2.1.1 + */ +MatrixIncludedComponents::= BIT STRING{ + xPosition (0), + yPosition (1), + zPosition (2), + xVelocityOrVelocityMagnitude (3), + yVelocityOrVelocityDirection (4), + zSpeed (5), + xAccelOrAccelMagnitude (6), + yAccelOrAccelDirection (7), + zAcceleration (8), + zAngle (9), + yAngle (10), + xAngle (11), + zAngularVelocity (12) +} (SIZE(13,...)) + +/** + * This DE represents the type of facility layer message. + * + * The value shall be set to: + * - 1 - `denm` - for Decentralized Environmental Notification Message (DENM) as specified in ETSI EN 302 637-3 [2], + * - 2 - `cam` - for Cooperative Awareness Message (CAM) as specified in ETSI EN 302 637-2 [1], + * - 3 - `poim` - for Point of Interest Message as specified in ETSI TS 103 916 [9], + * - 4 - `spatem` - for Signal Phase And Timing Extended Message (SPATEM) as specified in ETSI TS 103 301 [15], + * - 5 - `mapem` - for MAP Extended Message (MAPEM) as specified in ETSI TS 103 301 [15], + * - 6 - `ivim` - for in Vehicle Information Message (IVIM) as specified in ETSI TS 103 301 [15], + * - 7 - `rfu1` - reserved for future usage, + * - 8 - `rfu2` - reserved for future usage, + * - 9 - `srem` - for Signal Request Extended Message as specified in ETSI TS 103 301 [15], + * - 10 - `ssem` - for Signal request Status Extended Message as specified in ETSI TS 103 301 [15], + * - 11 - `evcsn` - for Electrical Vehicle Charging Spot Notification message as specified in ETSI TS 101 556-1 [9], + * - 12 - `saem` - for Services Announcement Extended Message as specified in ETSI EN 302 890-1 [17], + * - 13 - `rtcmem` - for Radio Technical Commission for Maritime Services Extended Message (RTCMEM) as specified in ETSI TS 103 301 [15], + * - 14 - `cpm` - for Collective Perception Message (CPM) as specified in ETSI TS 103 324 [10], + * - 15 - `imzm` - for Interference Management Zone Message (IMZM) as specified in ETSI TS 103 724 [13], + * - 16 - `vam` - for Vulnerable Road User Awareness Message as specified in ETSI TS 130 300-3 [12], + * - 17 - `dsm` - reserved for Diagnosis, logging and Status Message, + * - 18 - `mim` - for Marshalling Infrastructure Message as specified in ETSI TS TS 103 882 [11], + * - 19 - `mvm` - for Marshalling Vehicle Message as specified in ETSI TS TS 103 882 [11], + * - 20 - `mcm` - reserved for Manoeuvre Coordination Message, + * - 21-255 - reserved for future usage. + * + * @category: Communication information + * @revision: Created in V2.1.1 from @ref ItsPduHeader. Value 3 re-assigned to poim and value 7 and 8 reserved in V2.2.1, values 18 and 19 assigned in V2.3.1 + */ +MessageId::= INTEGER { + denm (1), + cam (2), + poim (3), + spatem (4), + mapem (5), + ivim (6), + rfu1 (7), + rfu2 (8), + srem (9), + ssem (10), + evcsn (11), + saem (12), + rtcmem (13), + cpm (14), + imzm (15), + vam (16), + dsm (17), + mim (18), + mvm (19), + mcm (20) +} (0..255) + +/** + * This DE represents the number of occupants in a vehicle. + * + * The value shall be set to: + * - `n` (`n >= 0` and `n < 126`) for the number n of occupants, + * - `126` for values equal to or higher than 125, + * - `127` if information is not available. + * + * @unit: 1 person + * @category: Vehicle information + * @revision: Editorial update in V2.1.1 + */ +NumberOfOccupants ::= INTEGER { + outOfRange (126), + unavailable (127) +} (0 .. 127) + +/** + * This DE represents a single-value indication about the overall information quality of a perceived object. + * + * The value shall be set to: + * - `0` : if there is no confidence in detected object, e.g. for "ghost"-objects or if confidence could not be computed, + * - `n` (`n > 0` and `n < 15`) : for the applicable confidence value, + * - `15` : if there is full confidence in the detected Object. + * + * @unit n/a + * @category: Sensing information + * @revision: Created in V2.1.1 +*/ +ObjectPerceptionQuality ::= INTEGER { + noConfidence (0), + fullConfidence (15) +} (0..15) + +/** + * This DE represents a single dimension of an object. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 255`) if the accuracy is equal to or less than n x 0,1 m, and more than (n-1) x 0,1 m, + * - `255` if the accuracy is out of range i.e. greater than 25,4 m, + * - `256` if the data is unavailable. + * + * @unit 0,1 m + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +ObjectDimensionValue ::= INTEGER { + outOfRange (255), + unavailable (256) +}(1..256) + +/** + * This DE indicates the object dimension confidence value which represents the estimated absolute accuracy of an object dimension value with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 31`) if the confidence value is equal to or less than n x 0,1 metre, and more than (n-1) x 0,1 metre, + * - `31` if the confidence value is out of range i.e. greater than 3,0 m, + * - `32` if the confidence value is unavailable. + * + * @unit 0,1 m + * @category: Sensing information + * @revision: Created in V2.1.1 +*/ +ObjectDimensionConfidence ::= INTEGER { + outOfRange (31), + unavailable (32) +} (1..32) + +/** + * This DE indicates the face or part of a face of a solid object. + * + * The object is modelled as a rectangular prism that has a length that is greater than its width, with the faces of the object being defined as: + * - front: the face defined by the prism's width and height, and which is the first face in direction of longitudinal movement of the object, + * - back: the face defined by the prism's width and height, and which is the last face in direction of longitudinal movement of the object, + * - side: the faces defined by the prism's length and height with "left" and "right" defined by looking at the front face and "front" and "back" defined w.r.t to the front and back faces. + * + * Note: It is permissible to derive the required object dimensions and orientation from models to provide a best guess. + * + * @category: Basic information + * @revision: V2.1.1 +*/ +ObjectFace ::= ENUMERATED { + front (0), + sideLeftFront (1), + sideLeftBack (2), + sideRightFront (3), + sideRightBack (4), + back (5) +} + +/** + * This DE represents a time period to describe the opening days and hours of a Point of Interest. + * (for example local commerce). + * + * @category: Basic information + * @revision: V1.3.1 + */ +OpeningDaysHours ::= UTF8String + +/** + * The DE represents an ordinal number that indicates the position of an element in a set. + * + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +OrdinalNumber1B ::= INTEGER(0..255) + + +/** + * The DE represents an ordinal number that indicates the position of an element in a set. + * + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +OrdinalNumber3b ::= INTEGER(1..8) + +/** + * This DE indicates the subclass of a detected object for @ref ObjectClass "otherSubclass". + * + * The value shall be set to: + * - `0` - unknown - if the subclass is unknown. + * - `1` - singleObject - if the object is a single object. + * - `2` - multipleObjects - if the object is a group of multiple objects. + * - `3` - bulkMaterial - if the object is a bulk material. + * + * @category: Sensing information + * @revision: Created in V2.1.1 + */ +OtherSubClass ::= INTEGER { + unknown (0), + singleObject (1), + multipleObjects (2), + bulkMaterial (3) +} (0..255) + +/** + * This DE indicates the arrangement of parking space in a parking area. + * + * The value shall be set to: + * - `0` to indicate that the parking spaces are arranged in a line and parallel to a road or curb, + * - `1` to indicate that the parking spaces are arranged side-by-side and diagonally to a curb, + * - `2` to indicate that the parking spaces are arranged side-by-side and perpendicularly to a curb, + * - `3` to indicate that the parking spaces are arranged so that vehicles form a queue, + * - `4` to indicate that the parking spaces are arranged in a mixed fashion, + * - 5-7 - reserved for future usage. + * + * @category: Road topology information + * @revision: Created in V2.3.1 +*/ +ParkingAreaArrangementType ::= INTEGER { + parallelParkingSpace (0), + diagonalParkingSpace (1), + perpendicularParkingSpace (2), + queueParking (3), + mixed (4), + unknown (7) +} (0..7) + +/** + * This DE indicates the type of a reservation of a parking space/area. + * + * The value shall be set to: + * - `0` to indicate that it is reserved to disabled persons, + * - `1` to indicate that it is reserved to pregnant women, + * - `2` to indicate that it is reserved to women, + * - `3` to indicate that it is reserved to parents with small children, + * - `4` to indicate that it is reserved for loading and unloading of goods, + * - `5` to indicate that it is reserved for manual charging of electric vehicles, + * - `6` to indicate that it is reserved for automated charging of electric vehicles, + * - `7` to indicate that it is reserved for vehicles carrying out refrigerated transport of goods, + * - `8` to indicate that it is reserved for VIPs, + * - `9` to indicate that it is reserved for pre-booked reservations only, + * - `10` to indicate that it is not reserved and can still be reserved, + * - `11` to indicate that it cannot be reserved, + * - `12` to indicate that it reserved for drop-off and pick-up of vehicles for automated valet parking, + * - `13` to indicate that it is reserved for vehicles with a permit, + * - 14-31 - reserved for future usage. + * + * @category: Road topology information + * @revision: Created in V2.3.1 +*/ +ParkingReservationType ::= INTEGER { + disabled (0), + pregnant (1), + womenOnly (2), + parentAndChild (3), + loadAndOffloadGoods (4), + manualElectricVehicleCharging (5), + automatedElectricVehicleCharging (6), + refriferatedTransport (7), + vip (8), + preBooking (9), + freeToBeReserved (10), + reservationNotPossible (11), + automatedValetparking (12), + permit (13) +}(0..31) + + +/** + * This DE represents the recorded or estimated travel time between a position and a predefined reference position. + * + * @unit 0,01 second + * @category: Basic information + * @revision: V1.3.1 + */ +PathDeltaTime ::= INTEGER (1..65535, ...) + +/** + * This DE indicates an ordinal number that represents the position of a component in the list of @ref Traces or @ref TracesExtended. + * + * The value shall be set to: + * - `0` - noPath - if no path is identified + * - `1..7` - for instances 1..7 of @ref Traces + * - `8..14` - for instances 1..7 of @ref TracesExtended. + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ +PathId ::= INTEGER { + noPath (0), + path1 (1), + path2 (2), + path3 (3), + path4 (4), + path5 (5), + path6 (6), + path7 (7), + pathExtended1 (8), + pathExtended2 (9), + pathExtended3 (10), + pathExtended4 (11), + pathExtended5 (12), + pathExtended6 (13), + pathExtended7 (14) +} (0..14) + +/** + * This DE represents the position of a vehicle pedal (e.g. brake or accelerator pedal). + * + * @unit: 10% + * @category: Vehicle information + * @revision: Created in V2.3.1 +*/ +PedalPositionValue::= INTEGER { + notPressed (0), + fullyPressed (10), + unavailable (11) +} (0..11) + +/** + * This DE denotes the ability of an ITS-S to provide information fullfilling additional requirements. + * A performance class value is used to describe characteristics of data. The semantic defintion of the values are out of scope of the present document + * and should be subject to profiling. + * + * The value shall be set to: + * - `0` if the performance class is unknown, + * - `1` for performance class A, + * - `2` for performance class B, + * - 3-7 reserved for future use. + * + * @category: Vehicle information + * @revision: Editorial update in V2.1.1, description changed in V2.3.1 + */ +PerformanceClass ::= INTEGER { + unavailable (0), + performanceClassA (1), + performanceClassB (2) +} (0..7) + +/** + * This DE represents a telephone number + * + * @category: Basic information + * @revision: V1.3.1 + */ +PhoneNumber ::= NumericString (SIZE(1..16)) + +/** + * This DE indicates the perpendicular distance from the centre of mass of an empty load vehicle to the front line of + * the vehicle bounding box of the empty load vehicle. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 62`) for any aplicable value n between 0,1 metre and 6,2 metres, + * - `62` for values equal to or higher than 6.1 metres, + * - `63` if the information is unavailable. + * + * @note: The empty load vehicle is defined in ISO 1176 [8], clause 4.6. + * + * @unit 0,1 metre + * @category Vehicle information + * @revision: description revised in V2.1.1 (the meaning of 62 has changed slightly) + */ +PosCentMass ::= INTEGER { + tenCentimetres (1), + outOfRange (62), + unavailable (63) +} (1..63) + +/** + * This DE indicates the positioning technology being used to estimate a geographical position. + * + * The value shall be set to: + * - 0 `noPositioningSolution` - no positioning solution used, + * - 1 `sGNSS` - Global Navigation Satellite System used, + * - 2 `dGNSS` - Differential GNSS used, + * - 3 `sGNSSplusDR` - GNSS and dead reckoning used, + * - 4 `dGNSSplusDR` - Differential GNSS and dead reckoning used, + * - 5 `dR` - dead reckoning used, + * - 6 `manuallyByOperator` - position set manually by a human operator. + * + * @category: GeoReference information + * @revision: V1.3.1, extension with value 6 added in V2.2.1 + */ +PositioningSolutionType ::= ENUMERATED { + noPositioningSolution (0), + sGNSS (1), + dGNSS (2), + sGNSSplusDR (3), + dGNSSplusDR (4), + dR (5), + ..., + manuallyByOperator (6) +} + +/** + * This DE indicates whether a passenger seat is occupied or whether the occupation status is detectable or not. + * + * The number of row in vehicle seats layout is counted in rows from the driver row backwards from front to the rear + * of the vehicle. + * The left side seat of a row refers to the left hand side seen from vehicle rear to front. + * Additionally, a bit is reserved for each seat row, to indicate if the seat occupation of a row is detectable or not, + * i.e. `row1NotDetectable (3)`, `row2NotDetectable(8)`, `row3NotDetectable(13)` and `row4NotDetectable(18)`. + * Finally, a bit is reserved for each row seat to indicate if the seat row is present or not in the vehicle, + * i.e. `row1NotPresent (4)`, `row2NotPresent (9)`, `row3NotPresent(14)`, `row4NotPresent(19)`. + * + * When a seat is detected to be occupied, the corresponding seat occupation bit shall be set to `1`. + * For example, when the row 1 left seat is occupied, `row1LeftOccupied(0)` bit shall be set to `1`. + * When a seat is detected to be not occupied, the corresponding seat occupation bit shall be set to `0`. + * Otherwise, the value of seat occupation bit shall be set according to the following conditions: + * - If the seat occupation of a seat row is not detectable, the corresponding bit shall be set to `1`. + * When any seat row not detectable bit is set to `1`, all corresponding seat occupation bits of the same row + * shall be set to `1`. + * - If the seat row is not present, the corresponding not present bit of the same row shall be set to `1`. + * When any of the seat row not present bit is set to `1`, the corresponding not detectable bit for that row + * shall be set to `1`, and all the corresponding seat occupation bits in that row shall be set to `0`. + * + * @category: Vehicle information + * @revision: V1.3.1 + */ +PositionOfOccupants ::= BIT STRING { + row1LeftOccupied (0), + row1RightOccupied (1), + row1MidOccupied (2), + row1NotDetectable (3), + row1NotPresent (4), + row2LeftOccupied (5), + row2RightOccupied (6), + row2MidOccupied (7), + row2NotDetectable (8), + row2NotPresent (9), + row3LeftOccupied (10), + row3RightOccupied (11), + row3MidOccupied (12), + row3NotDetectable (13), + row3NotPresent (14), + row4LeftOccupied (15), + row4RightOccupied (16), + row4MidOccupied (17), + row4NotDetectable (18), + row4NotPresent (19) +} (SIZE(20)) + +/** + * This DE indicates the perpendicular distance between the vehicle front line of the bounding box and the front wheel axle in 0,1 metre. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 19`) for any aplicable value between 0,1 metre and 1,9 metres, + * - `19` for values equal to or higher than 1.8 metres, + * - `20` if the information is unavailable. + * + * @category: Vehicle information + * @unit 0,1 metre + * @revision: description revised in V2.1.1 (the meaning of 19 has changed slightly) + */ +PosFrontAx ::= INTEGER { + outOfRange (19), + unavailable(20) +} (1..20) + +/** + * This DE represents a position along a single dimension such as the middle of a road or lane, measured as an offset from an externally defined starting point, + * in direction of an externally defined reference direction. + * + * The value shall be set to: + * - `n` (`n >= -8190` and `n < 0`) if the position is equal to or less than n x 1 metre and more than (n-1) x 1 metre, in opposite direction of the reference direction, + * - `0` if the position is at the starting point, + * - `n` (`n > 0` and `n < 8190`) if the position is equal to or less than n x 1 metre and more than (n-1) x 1 metre, in the same direction as the reference direction, + * - `8 190` if the position is out of range, i.e. equal to or greater than 8 189 m, + * - `8 191` if the position information is not available. + * + * @unit 1 metre + * @category: GeoReference information + * @revision: Created in V2.2.1 + */ +Position1d ::= INTEGER { + outOfRange(8190), + unavailable(8191) +}(-8190..8191) + +/** + * This DE represents the distance from the centre of vehicle front bumper to the right or left longitudinal carrier of vehicle. + * The left/right carrier refers to the left/right as seen from a passenger sitting in the vehicle. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 126`) for any aplicable value between 0,01 metre and 1,26 metres, + * - `126` for values equal to or higher than 1.25 metres, + * - `127` if the information is unavailable. + * + * @unit 0,01 metre + * @category Vehicle information + * @revision: description revised in V2.1.1 (the meaning of 126 has changed slightly) + */ +PosLonCarr ::= INTEGER { + outOfRange (126), + unavailable (127) +} (1..127) + +/** + * This DE represents the perpendicular inter-distance of neighbouring pillar axis of vehicle starting from the + * middle point of the front line of the vehicle bounding box. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 29`) for any aplicable value between 0,1 metre and 2,9 metres, + * - `29` for values equal to or greater than 2.8 metres, + * - `30` if the information is unavailable. + * + * @unit 0,1 metre + * @category Vehicle information + * @revision: description revised in V2.1.1 (the meaning of 29 has changed slightly) + */ +PosPillar ::= INTEGER { + outOfRange (29), + unavailable (30) +} (1..30) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `postCrash` . + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information on post crash event is unavailable, + * - 1 `accidentWithoutECallTriggered` - in case no eCall has been triggered for an accident, + * - 2 `accidentWithECallManuallyTriggered` - in case eCall has been manually triggered and transmitted to eCall back end, + * - 3 `accidentWithECallAutomaticallyTriggered` - in case eCall has been automatically triggered and transmitted to eCall back end, + * - 4 `accidentWithECallTriggeredWithoutAccessToCellularNetwork` - in case eCall has been triggered but cellular network is not accessible from triggering vehicle. + * - 5-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +PostCrashSubCauseCode ::= INTEGER { + unavailable (0), + accidentWithoutECallTriggered (1), + accidentWithECallManuallyTriggered (2), + accidentWithECallAutomaticallyTriggered (3), + accidentWithECallTriggeredWithoutAccessToCellularNetwork (4) +} (0..255) + +/** +* This DE represent the total amount of rain falling during one hour. It is measured in mm per hour at an area of 1 square metre. +* +* The following values are specified: +* - `n` (`n > 0` and `n < 2000`) if the amount of rain falling is equal to or less than n x 0,1 mm/h and greater than (n-1) x 0,1 mm/h, +* - `2000` if the amount of rain falling is greater than 199.9 mm/h, +* - `2001` if the information is not available. +* +* @unit: 0,1 mm/h +* @category: Basic Information +* @revision: created in V2.1.1 +*/ +PrecipitationIntensity ::= INTEGER { + outOfRange (2000), + unavailable (2001) +} (1..2001) + +/** + * This DE represents the indentifier of a protected communication zone. + * + * + * @category: Infrastructure information, Communication information + * @revision: Revision in V2.1.1 (changed name from ProtectedZoneID to ProtectedZoneId) + */ +ProtectedZoneId ::= INTEGER (0.. 134217727) + +/** + * This DE represents the radius of a protected communication zone. + * + * + * @unit: metre + * @category: Infrastructure information, Communication information + * @revision: V1.3.1 + */ +ProtectedZoneRadius ::= INTEGER (1..255,...) + +/** + * This DE indicates the type of a protected communication zone, so that an ITS-S is aware of the actions to do + * while passing by such zone (e.g. reduce the transmit power in case of a DSRC tolling station). + * + * The protected zone type is defined in ETSI TS 102 792 [14]. + * + * + * @category: Communication information + * @revision: V1.3.1 + */ +ProtectedZoneType::= ENUMERATED { + permanentCenDsrcTolling (0), + ..., + temporaryCenDsrcTolling (1) +} + +/** + * This DE is used for various tasks in the public transportation environment, especially for controlling traffic + * signal systems to prioritize and speed up public transportation in urban area (e.g. intersection "_bottlenecks_"). + * The traffic lights may be controlled by an approaching bus or tram automatically. This permits "_In Time_" activation + * of the green phase, will enable the individual traffic to clear a potential traffic jam in advance. Thereby the + * approaching bus or tram may pass an intersection with activated green light without slowing down the speed due to + * traffic congestion. Other usage of the DE is the provision of information like the public transport line number + * or the schedule delay of a public transport vehicle. + * + * @category: Vehicle information + * @revision: V1.3.1 + */ +PtActivationData ::= OCTET STRING (SIZE(1..20)) + +/** + * This DE indicates a certain coding type of the PtActivationData data. + * + * The folowing value are specified: + * - 0 `undefinedCodingType` : undefined coding type, + * - 1 `r09-16CodingType` : coding of PtActivationData conform to VDV recommendation 420 [7], + * - 2 `vdv-50149CodingType` : coding of PtActivationData based on VDV recommendation 420 [7]. + * - 3 - 255 : reserved for alternative and future use. + * + * @category: Vehicle information + * @revision: V1.3.1 + */ +PtActivationType ::= INTEGER { + undefinedCodingType (0), + r09-16CodingType (1), + vdv-50149CodingType (2) +} (0..255) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `railwayLevelCrossing` . + * + * The value shall be set to: + * - 0 `unavailable` - in case no further detailed information on the railway level crossing status is available, + * - 1 `doNotCrossAbnormalSituation` - in case when something wrong is detected by equation or sensors of the railway level crossing, + including level crossing is closed for too long (e.g. more than 10 minutes long ; default value), + * - 2 `closed` - in case the crossing is closed or closing (barriers down), + * - 3 `unguarded` - in case the level crossing is unguarded (i.e a Saint Andrew cross level crossing without detection of train), + * - 4 `nominal` - in case the barriers are up and/or the warning systems are off, + * - 5 `trainApproaching` - in case a train is approaching and the railway level crossing is without barriers. + * - 6-255: reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1, description of value 2 and 4 changed and value 5 added in V2.3.1 + */ +RailwayLevelCrossingSubCauseCode ::= INTEGER { + unavailable (0), + doNotCrossAbnormalSituation (1), + closed (2), + unguarded (3), + nominal (4), + trainApproaching (5) +} (0..255) + +/** + * This DE describes a distance of relevance for information indicated in a message. + * + * The value shall be set to: + * - 0 `lessThan50m` - for distances below 50 m, + * - 1 `lessThan100m` - for distances below 100 m, + * - 2 `lessThan200m` - for distances below 200 m, + * - 3 `lessThan500m` - for distances below 300 m, + * - 4 `lessThan1000m` - for distances below 1 000 m, + * - 5 `lessThan5km` - for distances below 5 000 m, + * - 6 `lessThan10km` - for distances below 10 000 m, + * - 7 `over10km` - for distances over 10 000 m. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref StandardLength3b instead. + * + * @category: GeoReference information + * @revision: Editorial update in V2.1.1 + */ +RelevanceDistance ::= ENUMERATED { + lessThan50m(0), + lessThan100m(1), + lessThan200m(2), + lessThan500m(3), + lessThan1000m(4), + lessThan5km(5), + lessThan10km(6), + over10km(7) +} + +/** + * This DE indicates a traffic direction that is relevant to information indicated in a message. + * + * The value shall be set to: + * - 0 `allTrafficDirections` - for all traffic directions, + * - 1 `upstreamTraffic` - for upstream traffic, + * - 2 `downstreamTraffic` - for downstream traffic, + * - 3 `oppositeTraffic` - for traffic in the opposite direction. + * + * The terms `upstream`, `downstream` and `oppositeTraffic` are relative to the event position. + * + * @note: Upstream traffic corresponds to the incoming traffic towards the event position, + * and downstream traffic to the departing traffic away from the event position. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref TrafficDirection instead. + * + * @category: GeoReference information + * @revision: Editorial update in V2.1.1 + */ +RelevanceTrafficDirection ::= ENUMERATED { + allTrafficDirections(0), + upstreamTraffic(1), + downstreamTraffic(2), + oppositeTraffic(3) +} + +/** + * This DE indicates whether an ITS message is transmitted as request from ITS-S or a response transmitted from + * ITS-S after receiving request from other ITS-Ss. + * + * The value shall be set to: + * - 0 `request` - for a request message, + * - 1 `response` - for a response message. + * + * @category Communication information + * @revision: Editorial update in V2.1.1 + */ +RequestResponseIndication ::= ENUMERATED { + request (0), + response (1) +} + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `rescueAndRecoveryWorkInProgress` + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information on rescue and recovery work is unavailable, + * - 1 `emergencyVehicles` - in case rescue and/or safeguarding work is ongoing by emergency vehicles, i.e. by vehicles that have the absolute right of way, + * - 2 `rescueHelicopterLanding` - in case rescue helicopter is landing, + * - 3 `policeActivityOngoing` - in case police activity is ongoing (only to be used if a more specific sub cause than (1) is needed), + * - 4 `medicalEmergencyOngoing` - in case medical emergency recovery is ongoing (only to be used if a more specific sub cause than (1) is needed), + * - 5 `childAbductionInProgress` - in case a child kidnapping alarm is activated and rescue work is ongoing (only to be used if a more specific sub cause than (1) is needed), + * - 6 `prioritizedVehicle` - in case rescue and/or safeguarding work is ongoing by prioritized vehicles, i.e. by vehicles that have priority but not the absolute right of way, + * - 7 `rescueAndRecoveryVehicle` - in case technical rescue work is ongoing by rescue and recovery vehicles. + * - 8-255: reserved for future usage. + + * + * @category: Traffic information + * @revision: V1.3.1, named values 6 and 7 added in V2.2.1 + */ +RescueAndRecoveryWorkInProgressSubCauseCode ::= INTEGER { + unavailable (0), + emergencyVehicles (1), + rescueHelicopterLanding (2), + policeActivityOngoing (3), + medicalEmergencyOngoing (4), + childAbductionInProgress (5), + prioritizedVehicle (6), + rescueAndRecoveryVehicle (7) +} (0..255) + + +/** + * This DE indicates an ordinal number that represents the position of a component in the list @ref RoadConfigurationSectionList. + * + * The value shall be set to: + * - `0` - if no road section is identified + * - `1..8` - for instances 1..8 of @ref RoadConfigurationSectionList + * + * @category: Road topology information + * @revision: Created in V2.2.1 + */ + +RoadSectionId::= INTEGER (0..8, ...) + +/** + * This DE indicates the type of a road segment. + * + * The value shall be set to: + * - 0 `urban-NoStructuralSeparationToOppositeLanes` - for an urban road with no structural separation between lanes carrying traffic in opposite directions, + * - 1 `urban-WithStructuralSeparationToOppositeLanes` - for an urban road with structural separation between lanes carrying traffic in opposite directions, + * - 2 `nonUrban-NoStructuralSeparationToOppositeLanes` - for an non urban road with no structural separation between lanes carrying traffic in opposite directions, + * - 3 `nonUrban-WithStructuralSeparationToOppositeLanes` - for an non urban road with structural separation between lanes carrying traffic in opposite directions. + * + * @category: Road Topology Information + * @revision: Editorial update in V2.1.1 + */ +RoadType ::= ENUMERATED { + urban-NoStructuralSeparationToOppositeLanes (0), + urban-WithStructuralSeparationToOppositeLanes (1), + nonUrban-NoStructuralSeparationToOppositeLanes (2), + nonUrban-WithStructuralSeparationToOppositeLanes (3) +} + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `roadworks`. + * +The value shall be set to: + * - 0 `unavailable` - in case further detailed information on roadworks is unavailable, + * - 1 `majorRoadworks` - in case a major roadworks is ongoing, + * - 2 `roadMarkingWork` - in case a road marking work is ongoing, + * - 3 `slowMovingRoadMaintenance` - in case slow moving road maintenance work is ongoing, + * - 4 `shortTermStationaryRoadworks`- in case a short term stationary roadwork is ongoing, + * - 5 `streetCleaning` - in case a vehicle street cleaning work is ongoing, + * - 6 `winterService` - in case winter service work is ongoing, + * - 7 `setupPhase` - in case the work zone is being setup, + * - 8 `remodellingPhase` - in case the work zone is being changed, + * - 9 `dismantlingPhase` - in case the work zone is being dismantled after finished work. + * - 10-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1, values 7-9 added in V2.3.1 + */ +RoadworksSubCauseCode ::= INTEGER { + unavailable (0), + majorRoadworks (1), + roadMarkingWork (2), + slowMovingRoadMaintenance (3), + shortTermStationaryRoadworks (4), + streetCleaning (5), + winterService (6), + setupPhase (7), + remodellingPhase (8), + dismantlingPhase (9) +} (0..255) + +/** + * This DE indicates the driving automation level as defined in SAE J3016 [26]. + * + * @category: Vehicle information + * @revision: created in V2.3.1 +*/ +SaeAutomationLevel::= INTEGER (0..5) + +/** + * This DE indicates if a distance is safe. + * + * The value shall be set to: + * - `FALSE` if the triple {LaD, LoD, VD} < {MSLaD, MSLoD, MSVD} is simultaneously satisfied with confidence level of 90 % or more, + * - `TRUE` otherwise. + * + * @note: the abbreviations used are Lateral Distance (LaD), Longitudinal Distance (LoD) and Vertical Distance (VD) + * and their respective thresholds, Minimum Safe Lateral Distance (MSLaD), Minimum Safe Longitudinal Distance (MSLoD), and Minimum Safe Vertical Distance (MSVD). + * + * @category: Traffic information, Kinematic information + * @revision: Created in V2.1.1 +*/ +SafeDistanceIndicator::= BOOLEAN + +/** + * This DE indicates the horizontal position confidence value which represents the estimated absolute position accuracy, in one of the axis direction as defined in a shape of ellipse with a + * confidence level of 95 %. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 4 094`) if the accuracy is equal to or less than n * 0,01 metre, + * - `4 094` if the accuracy is out of range, i.e. greater than 4,093 m, + * - `4 095` if the accuracy information is unavailable. + * + * The value 0 shall not be used. + * + * @note: The fact that a position coordinate value is received with confidence value set to `unavailable(4095)`. + * can be caused by several reasons, such as: + * - the sensor cannot deliver the accuracy at the defined confidence level because it is a low-end sensor, + * - the sensor cannot calculate the accuracy due to lack of variables, or + * - there has been a vehicle bus (e.g. CAN bus) error. + * In all 3 cases above, the position coordinate value may be valid and used by the application. + * If a position coordinate value is received and its confidence value is set to `outOfRange(4094)`, it means that + * the position coordinate value is not valid and therefore cannot be trusted. Such value is not useful + * for the application. + + * @unit 0,01 metre + * @category: GeoReference Information + * @revision: Description revised in V2.1.1 + */ +SemiAxisLength ::= INTEGER{ + doNotUse (0), + outOfRange (4094), + unavailable (4095) +} (0..4095) + +/** + * This DE indicates the type of sensor. + * + * The value shall be set to: + * - 0 `undefined` - in case the sensor type is undefined, + * - 1 `radar` - in case the sensor is a radar, + * - 2 `lidar` - in case the sensor is a lidar, + * - 3 `monovideo` - in case the sensor is mono video, + * - 4 `stereovision` - in case the sensor is stereo vision, + * - 5 `nightvision` - in case the sensor supports night vision, using e.g. infrared illumination or thermal imaging, + * - 6 `ultrasonic` - in case the sensor is ultrasonic, + * - 7 `pmd` - in case the sensor is photonic mixing device, + * - 8 `inductionLoop` - in case the sensor is an induction loop, + * - 9 `sphericalCamera` - in case the sensor is a spherical camera, + * - 10 `uwb` - in case the sensor is ultra wide band, + * - 11 `acoustic` - in case the sensor is acoustic, + * - 12 `localAggregation` - in case the information is provided by a system that aggregates information from different local sensors. Aggregation may include fusion, + * - 13 `itsAggregation` - in case the information is provided by a system that aggregates information from other received ITS messages, + * - 14 `rfid` - in case the sensor is radio frequency identification using a passive or active (e.g. Bluetooth, W-LAN) technology. + * - 15-31 - are reserved for future usage. + * + * @category: Sensing Information + * @revision: created in V2.1.1, description of value 5 changed and value 14 added in V2.3.1 +*/ +SensorType ::= INTEGER { + undefined (0), + radar (1), + lidar (2), + monovideo (3), + stereovision (4), + nightvision (5), + ultrasonic (6), + pmd (7), + inductionLoop (8), + sphericalCamera (9), + uwb (10), + acoustic (11), + localAggregation (12), + itsAggregation (13), + rfid (14) +} (0..31) + +/** + * This DE indicates the type of sensor(s). + * The corresponding bit shall be set to 1 under the following conditions: + * + * - 0 `undefined` - in case the sensor type is undefined. + * - 1 `radar` - in case the sensor is a radar, + * - 2 `lidar` - in case the sensor is a lidar, + * - 3 `monovideo` - in case the sensor is mono video, + * - 4 `stereovision` - in case the sensor is stereo vision, + * - 5 `nightvision` - in case the sensor supports night vision, using e.g. infrared illumination or thermal imaging, + * - 6 `ultrasonic` - in case the sensor is ultrasonic, + * - 7 `pmd` - in case the sensor is photonic mixing device, + * - 8 `inductionLoop` - in case the sensor is an induction loop, + * - 9 `sphericalCamera` - in case the sensor is a spherical camera, + * - 10 `uwb` - in case the sensor is ultra wide band, + * - 11 `acoustic` - in case the sensor is acoustic, + * - 12 `localAggregation` - in case the information is provided by a system that aggregates information from different local sensors. Aggregation may include fusion, + * - 13 `itsAggregation` - in case the information is provided by a system that aggregates information from other received ITS messages, + * - 14 `rfid` - in case the sensor is radio frequency identification using a passive or active (e.g. Bluetooth, W-LAN) technology. + * - 15 - reserved for future usage. + * + * @note: If all bits are set to 0, then no sensor type is used + * + * @category: Sensing Information + * @revision: created in V2.2.1, description of value 5 changed and value 14 added in V2.3.1 +*/ +SensorTypes ::= BIT STRING { + undefined (0), + radar (1), + lidar (2), + monovideo (3), + stereovision (4), + nightvision (5), + ultrasonic (6), + pmd (7), + inductionLoop (8), + sphericalCamera (9), + uwb (10), + acoustic (11), + localAggregation (12), + itsAggregation (13), + rfid (14) +} (SIZE (16,... )) + +/** + * This DE represents a sequence number. + * + * @category: Basic information + * @revision: V1.3.1 + */ +SequenceNumber ::= INTEGER (0..65535) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `signalViolation`. + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information on signal violation event is unavailable, + * - 1 `stopSignViolation` - in case a stop sign violation is detected, + * - 2 `trafficLightViolation` - in case a traffic light violation is detected, + * - 3 `turningRegulationViolation`- in case a turning regulation violation is detected. + * - 4-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +SignalViolationSubCauseCode ::= INTEGER { + unavailable (0), + stopSignViolation (1), + trafficLightViolation (2), + turningRegulationViolation (3) +} (0..255) + +/** + * This DE represents the sub cause codes of the @ref CauseCode "slowVehicle". + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information on slow vehicle driving event is + * unavailable, + * - 1 `maintenanceVehicle` - in case of a slow driving maintenance vehicle on the road, + * - 2 `vehiclesSlowingToLookAtAccident`- in case vehicle is temporally slowing down to look at accident, spot, etc., + * - 3 `abnormalLoad` - in case an abnormal loaded vehicle is driving slowly on the road, + * - 4 `abnormalWideLoad` - in case an abnormal wide load vehicle is driving slowly on the road, + * - 5 `convoy` - in case of slow driving convoy on the road, + * - 6 `snowplough` - in case of slow driving snow plough on the road, + * - 7 `deicing` - in case of slow driving de-icing vehicle on the road, + * - 8 `saltingVehicles` - in case of slow driving salting vehicle on the road. + * - 9-255 - are reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +SlowVehicleSubCauseCode ::= INTEGER { + unavailable (0), + maintenanceVehicle (1), + vehiclesSlowingToLookAtAccident (2), + abnormalLoad (3), + abnormalWideLoad (4), + convoy (5), + snowplough (6), + deicing (7), + saltingVehicles (8) +} (0..255) + +/** + * The DE indicates if a vehicle is carrying goods in the special transport conditions. + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 `heavyLoad` - the vehicle is carrying goods with heavy load, + * - 1 `excessWidth` - the vehicle is carrying goods in excess of width, + * - 2 `excessLength` - the vehicle is carrying goods in excess of length, + * - 3 `excessHeight` - the vehicle is carrying goods in excess of height. + * + * Otherwise, the corresponding bit shall be set to 0. + * @category Vehicle information + * @revision: Description revised in V2.1.1 + */ +SpecialTransportType ::= BIT STRING { + heavyLoad (0), + excessWidth (1), + excessLength (2), + excessHeight (3) +} (SIZE(4)) + +/** + * This DE indicates the speed confidence value which represents the estimated absolute accuracy of a speed value with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 126`) if the confidence value is equal to or less than n * 0,01 m/s. + * - `126` if the confidence value is out of range, i.e. greater than 1,25 m/s, + * - `127` if the confidence value information is not available. + * + * @note: The fact that a speed value is received with confidence value set to `unavailable(127)` can be caused by several reasons, such as: + * - the sensor cannot deliver the accuracy at the defined confidence level because it is a low-end sensor, + * - the sensor cannot calculate the accuracy due to lack of variables, or + * - there has been a vehicle bus (e.g. CAN bus) error. + * In all 3 cases above, the speed value may be valid and used by the application. + * + * @note: If a speed value is received and its confidence value is set to `outOfRange(126)`, it means that the speed value is not valid + * and therefore cannot be trusted. Such is not useful for the application. + * + * @unit: 0,01 m/s + * @category: Vehicle information + * @revision: Description revised in V2.1.1 + */ +SpeedConfidence ::= INTEGER { + outOfRange (126), + unavailable (127) +} (1..127) + +/** + * This DE represents a speed limitation applied to a geographical position, a road section or a geographical region. + * + * @unit: km/h + * @category: Infrastructure information, Traffic information + * @revision: V1.3.1 + */ +SpeedLimit ::= INTEGER (1..255) + +/** + * This DE represents a speed value, i.e. the magnitude of the velocity-vector. + * + * The value shall be set to: + * - `0` in a standstill situation. + * - `n` (`n > 0` and `n < 16 382`) if the applicable value is equal to or less than n x 0,01 m/s, and greater than (n-1) x 0,01 m/s, + * - `16 382` for speed values greater than 163,81 m/s, + * - `16 383` if the speed accuracy information is not available. + * + * @note: the definition of standstill is out of scope of the present document. + * + * @unit: 0,01 m/s + * @category: Kinematic information + * @revision: Description revised in V2.1.1 (the meaning of 16382 has changed slightly) +*/ +SpeedValue ::= INTEGER { + standstill (0), + outOfRange (16382), + unavailable (16383) +} (0..16383) + +/** + * This DE indicates the type of stored information. + * + * The corresponding bit shall be set to 1 under the following conditions: + * + * - `0` undefined - in case the stored information type is undefined. + * - `1` staticDb - in case the stored information type is a static database. + * - `2` dynamicDb - in case the stored information type is a dynamic database + * - `3` realTimeDb - in case the stored information type is a real time updated database. + * - `4` map - in case the stored information type is a road topology map. + * - Bits 5 to 7 - are reserved for future use. + * + * @note: If all bits are set to 0, then no stored information type is used + * + * @category: Basic Information + * @revision: created in V2.2.1 +*/ +StoredInformationType::= BIT STRING { + undefined (0), + staticDb (1), + dynamicDb (2), + realTimeDb (3), + map (4) +} (SIZE (8,... )) + +/** + * This DE represents the value of a velocity component in a defined coordinate system. + * + * The value shall be set to: + * - `-16 383` if the velocity is equal to or smaller than -163,83 m/s, + * - `n` (`n > -16 383` and `n < 16 382`) if the applicable value is equal to or less than n x 0,01 m/s, and greater than (n-1) x 0,01 m/s, + * - `16 382` for velocity values equal to or greater than 163,81 m/s, + * - `16 383` if the velocity information is not available. + * + * @unit: 0,01 m/s + * @category: Kinematic information + * @revision: Created in V2.1.1 +*/ +VelocityComponentValue ::= INTEGER { + negativeOutOfRange (-16383), + positiveOutOfRange (16382), + unavailable (16383) +} (-16383..16383) + + +/** + * This DE indicates the estimated probability of a stability level and conversely also the probability of a stability loss. + * + * The value shall be set to: + * - `0` to indicate an estimated probability of a loss of stability of 0 %, i.e. "stable", + * - `n` (`n > 0` and `n < 50`) to indicate the actual stability level, + * - `50` to indicate a estimated probability of a loss of stability of 100 %, i.e. "total loss of stability", + * - the values between 51 and 62 are reserved for future use, + * - `63`: this value indicates that the information is unavailable. + * + * @unit: 2 % + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +StabilityLossProbability ::= INTEGER { + stable (0), + totalLossOfStability (50), + unavailable (63) +} (0..63) + +/** + * The DE represents length as a measure of distance between points or as a dimension of an object or shape. + * + * @unit: 0,1 metre + * @category: Basic information + * @revision: Created in V2.1.1 + */ +StandardLength12b::= INTEGER (0..4095) + +/** + * The DE represents length as a measure of distance between points. + * + * The value shall be set to: + * - 0 `lessThan50m` - for distances below 50 m, + * - 1 `lessThan100m` - for distances below 100 m, + * - 2 `lessThan200m` - for distances below 200 m, + * - 3 `lessThan500m` - for distances below 300 m, + * - 4 `lessThan1000m` - for distances below 1 000 m, + * - 5 `lessThan5km` - for distances below 5 000 m, + * - 6 `lessThan10km` - for distances below 10 000 m, + * - 7 `over10km` - for distances over 10 000 m. + * + * @category: GeoReference information + * @revision: Created in V2.1.1 from RelevanceDistance + */ +StandardLength3b ::= ENUMERATED { + lessThan50m (0), + lessThan100m (1), + lessThan200m (2), + lessThan500m (3), + lessThan1000m (4), + lessThan5km (5), + lessThan10km (6), + over10km (7) +} + +/** + * The DE represents length as a measure of distance between points or as a dimension of an object. + * + * @unit: 0,1 metre + * @category: Basic information + * @revision: Created in V2.1.1 + */ +StandardLength9b::= INTEGER (0..511) + +/** + * The DE represents length as a measure of distance between points or as a dimension of an object. + * + * @unit: 0,1 metre + * @category: Basic information + * @revision: Created in V2.1.1 + */ +StandardLength1B::= INTEGER (0..255) + +/** + * The DE represents length as a measure of distance between points or as a dimension of an object. + * + * @unit: 0,1 metre + * @category: Basic information + * @revision: Created in V2.1.1 + */ +StandardLength2B::= INTEGER (0..65535) + +/** + * This DE indicates the duration in minutes since which something is stationary. + * + * The value shall be set to: + * - 0 `lessThan1Minute` - for being stationary since less than 1 minute, + * - 1 `lessThan2Minutes` - for being stationary since less than 2 minute and for equal to or more than 1 minute, + * - 2 `lessThan15Minutes` - for being stationary since less than 15 minutes and for equal to or more than 1 minute, + * - 3 `equalOrGreater15Minutes` - for being stationary since equal to or more than 15 minutes. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +StationarySince ::= ENUMERATED { + lessThan1Minute (0), + lessThan2Minutes (1), + lessThan15Minutes (2), + equalOrGreater15Minutes (3) +} + +/** + * This DE provides the value of the sub cause codes of the @ref CauseCode "stationaryVehicle". + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information on stationary vehicle is unavailable, + * - 1 `humanProblem` - in case stationary vehicle is due to health problem of driver or passenger, + * - 2 `vehicleBreakdown` - in case stationary vehicle is due to vehicle break down, + * - 3 `postCrash` - in case stationary vehicle is caused by collision, + * - 4 `publicTransportStop` - in case public transport vehicle is stationary at bus stop, + * - 5 `carryingDangerousGoods`- in case the stationary vehicle is carrying dangerous goods, + * - 6 `vehicleOnFire` - in case of vehicle on fire. + * - 7-255 reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +StationaryVehicleSubCauseCode ::= INTEGER { + unavailable (0), + humanProblem (1), + vehicleBreakdown (2), + postCrash (3), + publicTransportStop (4), + carryingDangerousGoods (5), + vehicleOnFire (6) +} (0..255) + +/** + * This DE represents the identifier of an ITS-S. + * The ITS-S ID may be a pseudonym. It may change over space and/or over time. + * + * @category: Basic information + * @revision: Created in V2.1.1 based on @ref StationID + */ +StationId ::= INTEGER(0..4294967295) + +/** + * This DE represents the identifier of an ITS-S. + * The ITS-S ID may be a pseudonym. It may change over space and/or over time. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref StationId instead. + * @category: Basic information + * @revision: V1.3.1 + */ +StationID ::= INTEGER(0..4294967295) + +/** + * This DE represents the type of technical context the ITS-S is integrated in. + * The station type depends on the integration environment of ITS-S into vehicle, mobile devices or at infrastructure. + * + * The value shall be set to: + * - 0 `unknown` - information about the ITS-S context is not provided, + * - 1 `pedestrian` - ITS-S carried by human being not using a mechanical device for their trip (VRU profile 1), + * - 2 `cyclist` - ITS-S mounted on non-motorized unicycles, bicycles , tricycles, quadracycles (VRU profile 2), + * - 3 `moped` - ITS-S mounted on light motor vehicles with less than four wheels as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] + class L1, L2 (VRU Profile 3), + * - 4 `motorcycles` - ITS-S mounted on motor vehicles with less than four wheels as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] + class L3, L4, L5, L6, L7 (VRU Profile 3), + * - 5 `passengerCar` - ITS-S mounted on small passenger vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class M1, + * - 6 `bus` - ITS-S mounted on large passenger vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class M2, M3, + * - 7 `lightTruck` - ITS-S mounted on light Goods Vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class N1, + * - 8 `heavyTruck` - ITS-S mounted on Heavy Goods Vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class N2 and N3, + * - 9 `trailer` - ITS-S mounted on an unpowered vehicle that is intended to be towed by a powered vehicle as defined in + UNECE/TRANS/WP.29/78/Rev.4 [16] class O, + * - 10 `specialVehicles` - ITS-S mounted on vehicles which have special purposes other than the above (e.g. moving road works vehicle), + * - 11 `tram` - ITS-S mounted on a vehicle which runs on tracks along public streets, + * - 12 `lightVruVehicle` - ITS-S carried by a human being traveling on light vehicle , incl. possible use of roller skates or skateboards (VRU profile 2), + * - 13 `animal` - ITS-S carried by an animal presenting a safety risk to other road users e.g. domesticated dog in a city or horse (VRU Profile 4), + * - 14 - reserved for future usage, + * - 15 `roadSideUnit` - ITS-S mounted on an infrastructure typically positioned outside of the drivable roadway (e.g. on a gantry, on a pole, + on a stationary road works trailer); the infrastructure is static during the entire operation period of the ITS-S (e.g. no stop and go activity), + * - 16-255 - are reserved for future usage. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref TrafficParticipantType instead. + * @category: Communication information. + * @revision: revised in V2.1.1 (named values 12 and 13 added and note to value 9 deleted) + */ +StationType ::= INTEGER { + unknown (0), + pedestrian (1), + cyclist (2), + moped (3), + motorcycle (4), + passengerCar (5), + bus (6), + lightTruck (7), + heavyTruck (8), + trailer (9), + specialVehicle (10), + tram (11), + lightVruVehicle (12), + animal (13), + roadSideUnit (15) +} (0..255) + +/** + * This DE indicates the steering wheel angle confidence value which represents the estimated absolute accuracy for a steering wheel angle value with a confidence level of 95 %. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 126`) if the confidence value is equal to or less than n x 1,5 degrees, + * - `126` if the confidence value is out of range, i.e. greater than 187,5 degrees, + * - `127` if the confidence value is not available. + * + * @note: The fact that a steering wheel angle value is received with confidence value set to `unavailable(127)` + * can be caused by several reasons, such as: + * - the sensor cannot deliver the accuracy at the defined confidence level because it is a low-end sensor, + * - the sensor cannot calculate the accuracy due to lack of variables, or + * - there has been a vehicle bus (e.g. CAN bus) error. + * In all 3 cases above, the steering wheel angle value may be valid and used by the application. + * + * If a steering wheel angle value is received and its confidence value is set to `outOfRange(126)`, + * it means that the steering wheel angle value is not valid and therefore cannot be trusted. + * Such value is not useful for the application. + * + * @unit: 1,5 degree + * @category: Vehicle Information + * @revision: Description revised in V2.1.1 +*/ +SteeringWheelAngleConfidence ::= INTEGER { + outOfRange (126), + unavailable (127) +} (1..127) + +/** + * This DE represents the steering wheel angle of the vehicle at certain point in time. + * The value shall be provided in the vehicle coordinate system as defined in ISO 8855 [21], clause 2.11. + * + * The value shall be set to: + * - `-511` if the steering wheel angle is equal to or greater than 511 x 1,5 degrees = 766,5 degrees to the right, + * - `n` (`n > -511` and `n <= 0`) if the steering wheel angle is equal to or less than n x 1,5 degrees, and greater than (n-1) x 1,5 degrees, + turning clockwise (i.e. to the right), + * - `n` (`n >= 1` and `n < 511`) if the steering wheel angle is equal to or less than n x 0,1 degrees, and greater than (n-1) x 0,1 degrees, + turning counter-clockwise (i.e. to the left), + * - `511` if the steering wheel angle is greater than 510 x 1,5 degrees = 765 degrees to the left, + * - `512` if information is not available. + * + * @unit: 1,5 degree + * @revision: Description revised in V2.1.1 (meaning of value 511 has changed slightly). + */ +SteeringWheelAngleValue ::= INTEGER { + negativeOutOfRange (-511), + positiveOutOfRange (511), + unavailable (512) +} (-511..512) + +/** + * This DE indicates the generic sub cause of a detected event. + * + * @note: The sub cause code value assignment varies based on value of @ref CauseCode. + * + * @category: Traffic information + * @revision: Description revised in V2.1.1 (this is the generic sub cause type) + */ +SubCauseCodeType ::= INTEGER (0..255) + +/** + * This DE indicates a temperature value. + + * The value shall be set to: + * - `-60` for temperature equal to or less than -60 degrees C, + * - `n` (`n > -60` and `n < 67`) for the actual temperature n in degrees C, + * - `67` for temperature equal to or greater than 67 degrees C. + * + * @unit: degrees Celsius + * @category: Basic information + * @revision: Editorial update in V2.1.1 + */ +Temperature ::= INTEGER { + equalOrSmallerThanMinus60Deg (-60), + equalOrGreaterThan67Deg(67)} (-60..67) + +/** + * This DE represents the number of elapsed (TAI) milliseconds since the ITS Epoch. + * The ITS epoch is `00:00:00.000 UTC, 1 January 2004`. + * "Elapsed" means that the true number of milliseconds is continuously counted without interruption, + * i.e. it is not altered by leap seconds, which occur in UTC. + * + * @note: International Atomic Time (TAI) is the time reference coordinate on the basis of the readings of atomic clocks, + * operated in accordance with the definition of the second, the unit of time of the International System of Units. + * TAI is a continuous time scale. UTC has discontinuities, as it is occasionally adjusted by leap seconds. + * As of 1 January, 2022, TimestampIts is 5 seconds ahead of UTC, because since the ITS epoch on 1 January 2004 00:00:00.000 UTC, + * further 5 leap seconds have been inserted in UTC. + * + * EXAMPLE: The value for TimestampIts for 1 January 2007 00:00:00.000 UTC is `94 694 401 000` milliseconds, + * which includes one leap second insertion since the ITS epoch. + * @unit: 0,001 s + * @category: Basic information + * @revision: Description revised in in V2.1.1 + */ +TimestampIts ::= INTEGER (0..4398046511103) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `trafficCondition`. + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information on the traffic condition is unavailable, + * - 1 `increasedVolumeOfTraffic` - in case the type of traffic condition is increased traffic volume, + * - 2 `trafficJamSlowlyIncreasing` - in case the type of traffic condition is a traffic jam which volume is increasing slowly, + * - 3 `trafficJamIncreasing` - in case the type of traffic condition is a traffic jam which volume is increasing, + * - 4 `trafficJamStronglyIncreasing` - in case the type of traffic condition is a traffic jam which volume is strongly increasing, + * - 5 `trafficJam` ` - in case the type of traffic condition is a traffic jam and no further detailed information about its volume is available, + * - 6 `trafficJamSlightlyDecreasing` - in case the type of traffic condition is a traffic jam which volume is decreasing slowly, + * - 7 `trafficJamDecreasing` - in case the type of traffic condition is a traffic jam which volume is decreasing, + * - 8 `trafficJamStronglyDecreasing` - in case the type of traffic condition is a traffic jam which volume is decreasing rapidly, + * - 9 `trafficJamStable` - in case the traffic condition is a traffic jam with stable volume, + * - 10-255: reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1, definition of value 0 and 1 changed in V2.2.1, name and definition of value 5 changed in V2.2.1, value 9 added in V2.2.1 + */ +TrafficConditionSubCauseCode ::= INTEGER { + unavailable (0), + increasedVolumeOfTraffic (1), + trafficJamSlowlyIncreasing (2), + trafficJamIncreasing (3), + trafficJamStronglyIncreasing (4), + trafficJam (5), + trafficJamSlightlyDecreasing (6), + trafficJamDecreasing (7), + trafficJamStronglyDecreasing (8), + trafficJamStable (9) +} (0..255) + +/** + * This DE indicates a direction of traffic with respect to a reference direction, and a portion of that traffic with respect to a reference position. + * + * The value shall be set to: + * - 0 `allTrafficDirections` - for all directions of traffic, + * - 1 `sameAsReferenceDirection-upstreamOfReferencePosition` - for the direction of traffic according to the reference direction, and the portion of traffic upstream of the reference position, + * - 2 `sameAsReferenceDirection-downstreamOfReferencePosition` - for the direction of traffic according to the reference direction, and the portion of traffic downstream of the reference position, + * - 3 `oppositeToReferenceDirection` - for the direction of traffic opposite to the reference direction. + * + * @note: Upstream traffic corresponds to the incoming traffic towards the event position, and downstream traffic to the departing traffic away from the event position. + * @category: GeoReference information + * @revision: Created in V2.1.1 from RelevanceTrafficDirection, description and naming of values changed in V2.2.1 + * + */ + TrafficDirection ::= ENUMERATED { + allTrafficDirections(0), + sameAsReferenceDirection-upstreamOfReferencePosition(1), + sameAsReferenceDirection-downstreamOfReferencePosition(2), + oppositeToReferenceDirection(3) +} + +/** + * This DE represents the type of a traffic participant. + * + * The value shall be set to: + * - 0 `unknown` - information about traffic participant is not provided, + * - 1 `pedestrian` - human being not using a mechanical device for their trip (VRU profile 1), + * - 2 `cyclist` - non-motorized unicycles, bicycles , tricycles, quadracycles (VRU profile 2), + * - 3 `moped` - light motor vehicles with less than four wheels as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class L1, L2 (VRU Profile 3), + * - 4 `motorcycles` - motor vehicles with less than four wheels as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class L3, L4, L5, L6, L7 (VRU Profile 3), + * - 5 `passengerCar` - small passenger vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class M1, + * - 6 `bus` - large passenger vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class M2, M3, + * - 7 `lightTruck` - light Goods Vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class N1, + * - 8 `heavyTruck` - Heavy Goods Vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class N2 and N3, + * - 9 `trailer` - unpowered vehicle that is intended to be towed by a powered vehicle as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class O, + * - 10 `specialVehicles` - vehicles which have special purposes other than the above (e.g. moving road works vehicle), + * - 11 `tram` - vehicle which runs on tracks along public streets, + * - 12 `lightVruVehicle` - human being traveling on light vehicle, incl. possible use of roller skates or skateboards (VRU profile 2), + * - 13 `animal` - animal presenting a safety risk to other road users e.g. domesticated dog in a city or horse (VRU Profile 4), + * - 14 `agricultural` - agricultural and forestry vehicles as defined in UNECE/TRANS/WP.29/78/Rev.4 [16] class T, + * - 15 `roadSideUnit` - infrastructure typically positioned outside of the drivable roadway (e.g. on a gantry, on a pole, + on a stationary road works trailer); the infrastructure is static during the entire operation period of the ITS-S (e.g. no stop and go activity), + * - 16-255 - are reserved for future usage. + * + * @category: Communication information. + * @revision: Created in V2.1.1 based on StationType + */ +TrafficParticipantType ::= INTEGER { + unknown (0), + pedestrian (1), + cyclist (2), + moped (3), + motorcycle (4), + passengerCar (5), + bus (6), + lightTruck (7), + heavyTruck (8), + trailer (9), + specialVehicle (10), + tram (11), + lightVruVehicle (12), + animal (13), + agricultural (14), + roadSideUnit (15) +} (0..255) + +/** + * This DE indicates traffic rules that apply to vehicles at a certain position. + * + * The value shall be set to: + * - `0` - if overtaking is prohibited for all vehicles, + * - `1` - if overtaking is prohibited for trucks, + * - `2` - if vehicles should pass to the right lane, + * - `3` - if vehicles should pass to the left lane. + * - `4` - if vehicles should pass to the left or right lane. + * + * @category: Infrastructure information, Traffic information + * @revision: Editorial update in V2.1.1 + */ +TrafficRule ::= ENUMERATED { + noPassing (0), + noPassingForTrucks (1), + passToRight (2), + passToLeft (3), + ..., + passToLeftOrRight (4) +} + +/** + * This DE provides information about the presence of a trailer. + * + * The value shall be set to: + * - 0 `noTrailerPresent` - to indicate that no trailer is present, i.e. either the vehicle is physically not enabled to tow a trailer or it has been detected that no trailer is present. + * - 1 `trailerPresentWithKnownLength` - to indicate that a trailer has been detected as present and the length is included in the vehicle length value. + * - 2 `trailerPresentWithUnknownLength` - to indicate that a trailer has been detected as present and the length is not included in the vehicle length value. + * - 3 `trailerPresenceIsUnknown` - to indicate that information about the trailer presence is unknown, i.e. the vehicle is physically enabled to tow a trailer but the detection of trailer presence/absence is not possible. + * - 4 `unavailable` - to indicate that the information about the presence of a trailer is not available, i.e. it is neither known whether the vehicle is able to tow a trailer + * nor the detection of trailer presence/absence is possible. + * + * @category: Vehicle information + * @revision: Created in V2.1.1 based on VehicleLengthConfidenceIndication +*/ +TrailerPresenceInformation ::= ENUMERATED { + noTrailerPresent (0), + trailerPresentWithKnownLength (1), + trailerPresentWithUnknownLength (2), + trailerPresenceIsUnknown (3), + unavailable (4) +} + +/** + * This DE defines the probability that the ego trajectory intercepts with any other object's trajectory on the road. + * + * The value shall be set to: + * - `n` (`n >= 0` and `n <= 50`) to indicate the actual probability, + * - the values between 51 and 62 are reserved, + * - `63`: to indicate that the information is unavailable. + * + * @unit: 2 % + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +TrajectoryInterceptionProbability ::= INTEGER { + unavailable (63) +} (0..63) + +/** + * This DE defines the confidence level of the trajectoryInterceptionProbability. + * + * The value shall be set to: + * - `0` - to indicate confidence level less than 50 %, + * - `1` - to indicate confidence level greater than or equal to 50 % and less than 70 %, + * - `2` - to indicate confidence level greater than or equal to 70 % and less than 90 %, + * - `3` - to indicate confidence level greater than or equal to 90%. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +TrajectoryInterceptionConfidence ::= INTEGER { + lessthan50percent (0), + between50and70Percent (1), + between70and90Percent (2), + above90Percent (3) +} (0..3) + +/** + * This DE represents the time interval between two consecutive message transmissions. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref DeltaTimeMilliSecondPos instead. + * @unit: 0,001 s + * @category: Basic information + * @revision: V1.3.1 + */ +TransmissionInterval::= INTEGER (1..10000) + +/** + * This DE provides the turning direction. + * + * The value shall be set to: + * - `left` for turning to te left. + * - `right` for turing to the right. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +TurningDirection::= ENUMERATED { + left, + right +} + +/** + * This DE represents the smallest circular turn (i.e. U-turn) that the vehicle is capable of making. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 254`) to indicate the applicable value is equal to or less than n x 0,4 metre, and greater than (n-1) x 0,4 metre, + * - `254` to indicate that the turning radius is greater than 253 x 0,4 metre = 101.2 metres, + * - `255` to indicate that the information is unavailable. + * + * For vehicle with tracker, the turning radius applies to the vehicle only. + * + * @category: Vehicle information + * @unit 0,4 metre + * @revision: Description revised V2.1.1 (the meaning of 254 has changed slightly) + */ +TurningRadius ::= INTEGER { + outOfRange (254), + unavailable (255) +} (1..255) + +/** + * This DE represents an indication of how a certain path or area will be used. + * + * The value shall be set to: + * - 0 - ` noIndication ` - in case it will remain free to be used, + * - 1 - ` specialUse ` - in case it will be physically blocked by special use, + * - 2 - ` rescueOperation` - in case it is intended to be used for rescue operations, + * - 3 - ` railroad ` - in case it is intended to be used for rail traffic, + * - 4 - ` fixedRoute ` - in case it is intended to be used for fixed route traffic (e.g. bus line in service, delivery services, garbage truck in service etc.), + * - 5 - ` restrictedRoute ` - in case it is intended to be used for driving on restricted routes (e.g dedicated lanes/routes for heavy trucks or buses), + * - 6 - ` adasAd ` - in case it is intended to be used for driving with an active ADAS or AD system (see DE AccelerationControl or AutomationControl), + * - 7 - ` navigation ` - in case it is intended to be used for driving with an active navigation system. + * + * @category: Basic information + * @revision: Created in V2.2.1, extension 3-7 added in V2.3.1 + */ +UsageIndication ::= ENUMERATED { + noIndication(0), + specialUse (1), + rescueOperation (2), + ..., + railroad (3), + fixedRoute (4), + restrictedRoute (5), + adasAd (6), + navigation (7) +} + +/** + * This DE represents the duration of a traffic event validity. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref DeltaTimeSecond instead. + * @unit: 1 s + * @category: Basic information + * @revision: V1.3.1 +*/ +ValidityDuration::= INTEGER { + timeOfDetection(0), + oneSecondAfterDetection(1) +} (0..86400) + +/** + * This DE represents the Vehicle Descriptor Section (VDS). The values are assigned according to ISO 3779 [6]. + * + * @category: Vehicle information + * @revision: V1.3.1 + */ +VDS ::= IA5String (SIZE(6)) + +/** + * This DE represents the value of the sub cause codes of the @ref CauseCode `vehicleBreakdown`. + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information on cause of vehicle break down is unavailable, + * - 1 `lackOfFuel` - in case vehicle break down is due to lack of fuel, + * - 2 `lackOfBatteryPower` - in case vehicle break down is caused by lack of battery power, + * - 3 `engineProblem` - in case vehicle break down is caused by an engine problem, + * - 4 `transmissionProblem` - in case vehicle break down is caused by transmission problem, + * - 5 `engineCoolingProblem`- in case vehicle break down is caused by an engine cooling problem, + * - 6 `brakingSystemProblem`- in case vehicle break down is caused by a braking system problem, + * - 7 `steeringProblem` - in case vehicle break down is caused by a steering problem, + * - 8 `tyrePuncture` - in case vehicle break down is caused by tyre puncture, + * - 9 `tyrePressureProblem` - in case low tyre pressure in detected, + * - 10 `vehicleOnFire` - in case the vehicle is on fire. + * - 11-255 - are reserved for future usage. + * + * @category: Traffic information + + */ +VehicleBreakdownSubCauseCode ::= INTEGER { + unavailable (0), + lackOfFuel (1), + lackOfBatteryPower (2), + engineProblem (3), + transmissionProblem (4), + engineCoolingProblem (5), + brakingSystemProblem (6), + steeringProblem (7), + tyrePuncture (8), + tyrePressureProblem (9), + vehicleOnFire (10) +} (0..255) + +/** + * This DE represents the height of the vehicle, measured from the ground to the highest point, excluding any antennas. + * In case vehicles are equipped with adjustable ride heights, camper shells, and any other + * equipment which may result in varying height, the largest possible height shall be used. + * + * The value shall be set to: + * - `n` (`n >0` and `n < 127`) indicates the applicable value is equal to or less than n x 0,05 metre, and greater than (n-1) x 0,05 metre, + * - `127` indicates that the vehicle width is greater than 6,3 metres, + * - `128` indicates that the information in unavailable. + * + * @unit: 0,05 metre + * @category: Vehicle information + * @revision: created in V2.1.1 +*/ +VehicleHeight ::= INTEGER { + outOfRange (126), + unavailable (127) +}(1..128) + +/** + * This DE represents the height of the vehicle, measured from the ground to the highest point, excluding any antennas. + * In case vehicles are equipped with adjustable ride heights, camper shells, and any other + * equipment which may result in varying height, the largest possible height shall be used. + + * The value shall be set to: + * - `n` (`n > 0` and `n < 61`) indicates the applicable value is equal to or less than n x 0,1 metre, and greater than (n-1) x 0,1 metre, + * - `61` indicates that the vehicle height is greater than 6,0 metres, + * - `62` indicates that the information in unavailable. + * + * @unit: 0,1 metre + * @category: Vehicle information + * @revision: created in V2.3.1 based on VehicleHeight but better aligned in unit and range with VehicleWidth. + */ +VehicleHeight2 ::= INTEGER { + outOfRange (61), + unavailable (62) +} (1..62) + +/** + * This DE provides information about the presence of a trailer. + * + * The value shall be set to: + * - 0 `noTrailerPresent` - to indicate that no trailer is present, i.e. either the vehicle is physically not enabled to tow a trailer or it has been detected that no trailer is present, + * - 1 `trailerPresentWithKnownLength` - to indicate that a trailer has been detected as present and the length is included in the vehicle length value, + * - 2 `trailerPresentWithUnknownLength` - to indicate that a trailer has been detected as present and the length is not included in the vehicle length value, + * - 3 `trailerPresenceIsUnknown` - to indicate that information about the trailer presence is unknown, i.e. the vehicle is physically enabled to tow a trailer but the detection of trailer presence/absence is not possible, + * - 4 `unavailable` - to indicate that the information about the presence of a trailer is not available, i.e. it is neither known whether the vehicle is able to tow a trailer, + * nor the detection of trailer presence/absence is possible. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref TrailerPresenceInformation instead. + * @category: Vehicle information + * @revision: Description revised in V2.1.1 +*/ +VehicleLengthConfidenceIndication ::= ENUMERATED { + noTrailerPresent (0), + trailerPresentWithKnownLength (1), + trailerPresentWithUnknownLength (2), + trailerPresenceIsUnknown (3), + unavailable (4) +} + +/** + * This DE represents the length of a vehicle. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 1022`) to indicate the applicable value n is equal to or less than n x 0,1 metre, and greater than (n-1) x 0,1 metre, + * - `1 022` to indicate that the vehicle length is greater than 102.1 metres, + * - `1 023` to indicate that the information in unavailable. + * + * + * @unit: 0,1 metre + * @category: Vehicle information + * @revision: Description updated in V2.1.1 (the meaning of 1 022 has changed slightly). + */ +VehicleLengthValue ::= INTEGER { + outOfRange(1022), + unavailable(1023) +} (1..1023) + +/** + * This DE represents the mass of an empty loaded vehicle. + * + * The value shall be set to: + * - `n` (`n > 0` and `n < 1023`) to indicate that the applicable value is equal to or less than n x 10^5 gramm, and greater than (n-1) x 10^5 gramm, + * - `1 023` indicates that the vehicle mass is greater than 102 200 000 g, + * - `1 024` indicates the vehicle mass information is unavailable. + * + * @note: The empty load vehicle is defined in ISO 1176 [8], clause 4.6. + * + * @unit: 10^5 gramm + * @category: Vehicle information + * @revision: Description updated in V2.1.1 (the meaning of 1 023 has changed slightly). +*/ +VehicleMass ::= INTEGER { + outOfRange (1023), + unavailable(1024) +} (1..1024) + +/** + * This DE indicates the role played by a vehicle at a point in time. + * + * The value shall be set to: + * - 0 `default` - to indicate the default vehicle role as indicated by the vehicle type, + * - 1 `publicTransport` - to indicate that the vehicle is used to operate public transport service, + * - 2 `specialTransport` - to indicate that the vehicle is used for special transport purpose, e.g. oversized trucks, + * - 3 `dangerousGoods` - to indicate that the vehicle is used for dangerous goods transportation, + * - 4 `roadWork` - to indicate that the vehicle is used to realize roadwork or road maintenance mission, + * - 5 `rescue` - to indicate that the vehicle is used for rescue purpose in case of an accident, e.g. as a towing service, + * - 6 `emergency` - to indicate that the vehicle is used for emergency mission, e.g. ambulance, fire brigade, + * - 7 `safetyCar` - to indicate that the vehicle is used for public safety, e.g. patrol, + * - 8 `agriculture` - to indicate that the vehicle is used for agriculture, e.g. farm tractor, + * - 9 `commercial` - to indicate that the vehicle is used for transportation of commercial goods, + * - 10 `military` - to indicate that the vehicle is used for military purpose, + * - 11 `roadOperator` - to indicate that the vehicle is used in road operator missions, + * - 12 `taxi` - to indicate that the vehicle is used to provide an authorized taxi service, + * - 13 `uvar` - to indicate that the vehicle is authorized to enter a zone according to the applicable Urban Vehicle Access Restrictions. + * - 14 `rfu1` - is reserved for future usage. + * - 15 `rfu2` - is reserved for future usage. + * + * @category: Vehicle Information + * @revision: Description updated in V2.1.1 (removed reference to CEN/TS 16157-3), value 13 assigned in V2.2.1 + */ +VehicleRole ::= ENUMERATED { + default (0), + publicTransport (1), + specialTransport(2), + dangerousGoods (3), + roadWork (4), + rescue (5), + emergency (6), + safetyCar (7), + agriculture (8), + commercial (9), + military (10), + roadOperator (11), + taxi (12), + uvar (13), + rfu1 (14), + rfu2 (15) +} + +/** + * This DE represents the width of a vehicle, excluding side mirrors and possible similar extensions. + + * The value shall be set to: + * - `n` (`n > 0` and `n < 61`) indicates the applicable value is equal to or less than n x 0,1 metre, and greater than (n-1) x 0,1 metre, + * - `61` indicates that the vehicle width is greater than 6,0 metres, + * - `62` indicates that the information in unavailable. + * + * @unit: 0,1 metre + * @category: Vehicle information + * @revision: Description updated in V2.1.1 (the meaning of 61 has changed slightly). + */ +VehicleWidth ::= INTEGER { + outOfRange (61), + unavailable (62) +} (1..62) + +/** + * This DE represents the vehicle acceleration at vertical direction in the centre of the mass of the empty vehicle. + * The value shall be provided in the vehicle coordinate system as defined in ISO 8855 [21], clause 2.11. + * + * The value shall be set to: + * - `-160` for acceleration values equal to or less than -16 m/s^2, + * - `n` (`n > -160` and `n <= 0`) to indicate downwards acceleration equal to or less than n x 0,1 m/s^2, and greater than (n-1) x 0,1 m/s^2, + * - `n` (`n > 0` and `n < 160`) to indicate upwards acceleration equal to or less than n x 0,1 m/s^2, and greater than (n-1) x 0,1 m/s^2, + * - `160` for acceleration values greater than 15,9 m/s^2, + * - `161` when the data is unavailable. + * + * @note: The empty load vehicle is defined in ISO 1176 [8], clause 4.6. + * + * @category: Vehicle information + * @unit: 0,1 m/s^2 + * @revision: Desciption updated in V2.1.1 (the meaning of 160 has changed slightly). + * +*/ +VerticalAccelerationValue ::= INTEGER { + negativeOutOfRange (-160), + positiveOutOfRange (160), + unavailable (161) +} (-160 .. 161) + +/** + * This DE Identifies all the VRU profile types within a cluster. + * It consist of a Bitmap encoding VRU profiles, to allow multiple profiles to be indicated in a single cluster (heterogeneous cluster if more than one profile). + * + * The corresponding bit shall be set to 1 under the following conditions: + * - 0 `pedestrian` - indicates that the VRU cluster contains at least one pedestrian VRU, + * - 1 `bicycle` - indicates that the VRU cluster contains at least one bicycle VRU member, + * - 2 `motorcyclist`- indicates that the VRU cluster contains at least one motorcycle VRU member, + * - 3 `animal` - indicates that the VRU cluster contains at least one animal VRU member. + * + * Otherwise, the corresponding bit shall be set to 0. + * + * @category: VRU information + * @revision: Created in V2.1.1 +*/ +VruClusterProfiles ::= BIT STRING { + pedestrian (0), + bicyclist (1), + motorcyclist (2), + animal (3) +} (SIZE(4)) + +/** + * This DE represents the possible usage conditions of the VRU device. + + * - The value shall be set to: + * - 0 `unavailable` - to indicate that the usage conditions are unavailable, + * - 1 `other` - to indicate that the VRU device is in a state not defined below, + * - 2 `idle` - to indicate that the human is currently not interacting with the device, + * - 3 `listeningToAudio` - to indicate that any audio source other than calling is in use, + * - 4 `typing` - to indicate that the human is texting or performaing any other manual input activity, + * - 5 `calling` - to indicate that the VRU device is currently receiving a call, + * - 6 `playingGames` - to indicate that the human is playing games, + * - 7 `reading` - to indicate that the human is reading on the VRU device, + * - 8 `viewing` - to indicate that the human is watching dynamic content, including following navigation prompts, viewing videos or other visual contents that are not static. + * - value 9 to 15 - are reserved for future usage. + * + * @category: VRU information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 and range changed from 0..255 to 0..15 + */ +VruDeviceUsage ::= INTEGER { + unavailable (0), + other (1), + idle (2), + listeningToAudio (3), + typing (4), + calling (5), + playingGames (6), + reading (7), + viewing (8) +}(0..15) + +/** + * This DE represents the possible VRU environment conditions. + * + * - The value shall be set to: + * - 0 `unavailable` - to indicate that the information on the type of environment is unavailable, + * - 1 `intersectionCrossing` - to indicate that the VRU is on an intersection or crossing, + * - 2 `zebraCrossing` - to indicate that the VRU is on a zebra crossing (crosswalk), + * - 3 `sidewalk` - to indicate that the VRU is on a sidewalk, + * - 4 `onVehicleRoad` - to indicate that the VRU is on a traffic lane, + * - 5 `protectedGeographicArea`- to indicate that the VRU is in a protected area. + * - value 6 to 15 - are reserved for future usage. + * + * @category: VRU information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 and range changed from 0..255 to 0..15 + */ +VruEnvironment ::= INTEGER { + unavailable (0), + intersectionCrossing (1), + zebraCrossing (2), + sidewalk (3), + onVehicleRoad (4), + protectedGeographicArea (5) +}(0..15) + +/** + * This DE indicates the status of the possible human control over a VRU vehicle. + * + * The value shall be set to: + * - 0 `unavailable` - to indicate that the information is unavailable, + * - 1 `braking` - to indicate that the VRU is braking, + * - 2 `hardBraking` - to indicate that the VRU is braking hard, + * - 3 `stopPedaling` - to indicate that the VRU stopped pedaling, + * - 4 `brakingAndStopPedaling` - to indicate that the VRU stopped pedaling an is braking, + * - 5 `hardBrakingAndStopPedaling` - to indicate that the VRU stopped pedaling an is braking hard, + * - 6 `noReaction` - to indicate that the VRU is not changing its behavior. + * - 7 to 15 - are reserved for future usage. + * + * @category: VRU information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 and range changed from 0..255 to 0..15 + */ +VruMovementControl ::= INTEGER { + unavailable (0), + braking (1), + hardBraking (2), + stopPedaling (3), + brakingAndStopPedaling (4), + hardBrakingAndStopPedaling (5), + noReaction (6) +}(0..15) + +/** + * This DE indicates the profile of a pedestrian. + * + * The value shall be set to: + * - 0 `unavailable` - to indicate that the information on is unavailable, + * - 1 `ordinary-pedestrian` - to indicate a pedestrian to which no more-specific profile applies, + * - 2 `road-worker` - to indicate a pedestrian with the role of a road worker, + * - 3 `first-responder` - to indicate a pedestrian with the role of a first responder. + * - value 4 to 15 - are reserved for future usage. + * + * @category: VRU information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 + */ +VruSubProfilePedestrian ::= INTEGER { + unavailable (0), + ordinary-pedestrian (1), + road-worker (2), + first-responder (3) +}(0..15) + +/** + * This DE indicates the profile of a VRU and its light VRU vehicle / mounted animal. + * + * The value shall be set to: + * - 0 `unavailable` - to indicate that the information is unavailable, + * - 1 `bicyclist ` - to indicate a cycle and bicyclist to which no more-specific profile applies, + * - 2 `wheelchair-user` - to indicate a wheelchair and its user, + * - 3 `horse-and-rider` - to indicate a horse and rider, + * - 4 `rollerskater` - to indicate a roller-skater and skater, + * - 5 `e-scooter` - to indicate an e-scooter and rider, + * - 6 `personal-transporter` - to indicate a personal-transporter and rider, + * - 7 `pedelec` - to indicate a pedelec and rider to which no more-specific profile applies, + * - 8 `speed-pedelec` - to indicate a speed-pedelec and rider. + * - 9 `roadbike` - to indicate a road bicycle (or road pedelec) and rider, + * - 10 `childrensbike` - to indicate a children�s bicycle (or children�s pedelec) and rider, + * - 11 to 15 - are reserved for future usage. + * + * @category: VRU information + * @revision: Created in V2.1.1, values 9 and 10 assigned in V2.2.1 + */ +VruSubProfileBicyclist ::= INTEGER { + unavailable (0), + bicyclist (1), + wheelchair-user (2), + horse-and-rider (3), + rollerskater (4), + e-scooter (5), + personal-transporter (6), + pedelec (7), + speed-pedelec (8), + roadbike (9), + childrensbike (10) +}(0..15) + +/** + * This DE indicates the profile of a motorcyclist and corresponding vehicle. + * + * The value shall be set to: + * - 0 `unavailable ` - to indicate that the information is unavailable, + * - 1 `moped` - to indicate a moped and rider, + * - 2 `motorcycle` - to indicate a motorcycle and rider, + * - 3 `motorcycle-and-sidecar-right` - to indicate a motorcycle with sidecar on the right and rider, + * - 4 `motorcycle-and-sidecar-left` - to indicate a motorcycle with sidecar on the left and rider. + * - 5 to 15 - are reserved for future usage. + * + * @category: VRU information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 + */ +VruSubProfileMotorcyclist ::= INTEGER { + unavailable (0), + moped (1), + motorcycle (2), + motorcycle-and-sidecar-right (3), + motorcycle-and-sidecar-left (4) +}(0..15) + +/** + * This DE indicates the profile of an animal + * + * The value shall be set to: + * - 0 `unavailable` - to indicate that the information is unavailable, + * - 1 `wild-animal` - to indicate a animal living in the wildness, + * - 2 `farm-animal` - to indicate an animal beloning to a farm, + * - 3 `service-animal` - to indicate an animal that supports a human being. + * - 4 to 15 - are reserved for future usage. + * + * @category: VRU information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 + */ +VruSubProfileAnimal ::= INTEGER { + unavailable (0), + wild-animal (1), + farm-animal (2), + service-animal (3) +}(0..15) + +/** + * This DE indicates the approximate size of a VRU including the VRU vehicle used. + * + * The value shall be set to: + * - 0 `unavailable` - to indicate that there is no matched size class or due to privacy reasons in profile 1, + * - 1 `low` - to indicate that the VRU size class is low depending on the VRU profile, + * - 2 `medium` - to indicate that the VRU size class is medium depending on the VRU profile, + * - 3 `high` - to indicate that the VRU size class is high depending on the VRU profile. + * - 4 to 15 - are reserved for future usage. + * + * @category: VRU information + * @revision: Created in V2.1.1, type changed from ENUMERATED to INTEGER in V2.2.1 + */ +VruSizeClass ::= INTEGER { + unavailable (0), + low (1), + medium (2), + high (3) +}(0..15) + +/** + * This DE describes the status of the exterior light switches of a VRU. + * + * The value of each bit indicates the state of the switch, which commands the corresponding light. + * The bit corresponding to a specific light shall be set to 1, when the corresponding switch is turned on, either manually by the driver or VRU + * or automatically by a vehicle or VRU system: + * - 0 `unavailable` - indicates no information available, + * - 1 `backFlashLight ` - indicates the status of the back flash light, + * - 2 `helmetLight` - indicates the status of the helmet light, + * - 3 `armLight` - indicates the status of the arm light, + * - 4 `legLight` - indicates the status of the leg light, + * - 5 `wheelLight` - indicates the status of the wheel light. + * - Bits 6 to 8 - are reserved for future use. + * The bit values do not indicate if the corresponding lamps are alight or not. + * If VRU is not equipped with a certain light or if the light switch status information is not available, the corresponding bit shall be set to 0. + * + * @category: VRU information + * @revision: Created in V2.1.1 + */ +VruSpecificExteriorLights ::= BIT STRING { + unavailable (0), + backFlashLight (1), + helmetLight (2), + armLight (3), + legLight (4), + wheelLight (5) +} (SIZE(8)) + +/** + * This DE indicates the perpendicular distance between front and rear axle of the wheel base of vehicle. + * + * The value shall be set to: + * - `n` (`n >= 1` and `n < 126`) if the value is equal to or less than n x 0,1 metre and more than (n-1) x 0,1 metre, + * - `126` indicates that the wheel base distance is equal to or greater than 12,5 metres, + * - `127` indicates that the information is unavailable. + * + * @unit 0,1 metre + * @category: Vehicle information + * @revision: Created in V2.1.1 + */ +WheelBaseVehicle ::= INTEGER { + outOfRange (126), + unavailable (127) +} (1..127) + +/** + * This DE indicates the angle confidence value which represents the estimated accuracy of an angle value with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `n` (`n >= 1` and `n < 126`) if the confidence value is equal to or less than n x 0,1 degrees and more than (n-1) x 0,1 degrees, + * - `126` if the confidence value is out of range, i.e. greater than 12,5 degrees, + * - `127` if the confidence value is not available. + * + * + * @unit 0,1 degrees + * @category: GeoReference Information + * @revision: Created in V2.1.1 +*/ +Wgs84AngleConfidence ::= INTEGER { + outOfRange (126), + unavailable (127) +} (1..127) + + +/** + * This DE represents an angle value in degrees described in the WGS84 reference system with respect to the WGS84 north. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * When the information is not available, the DE shall be set to 3 601. The value 3600 shall not be used. + * + * @unit 0,1 degrees + * @category: GeoReference Information + * @revision: Created in V2.1.1 +*/ +Wgs84AngleValue ::= INTEGER { + wgs84North (0), + wgs84East (900), + wgs84South (1800), + wgs84West (2700), + doNotUse (3600), + unavailable (3601) +} (0..3601) + +/** + * This DE indicates the actual status of the front wipers of the vehicle. + * + * The value shall be set to: + * - 0 `unavailable` - to indicate that the information is unavailable, + * - 1 `off` - to indicate that the wipers are switched off, + * - 2 `intermittent` - to indicate that the wipers are moving intermittently, + * - 3 `low` - to indicate that the wipers are moving at low speed, + * - 4 `high` - to indicate that the wipers are moving at high speed, + * - values 5 to 7 - are reserved for future usage. + * + * @note: the status can be either set manually by the driver or automatically by e.g. a rain sensor. The way the status is set does not affect the status itself. + * @category: Vehicle information + * @revision: created in V2.3.1 + */ +WiperStatus ::= INTEGER { + unavailable (0), + off (1), + intermittent (2), + low (3), + high (4) +} (0..7) + +/** + * This DE represents the World Manufacturer Identifier (WMI). The values are assigned according to ISO 3779 [6]. + * + * + * @category: Vehicle information + * @revision: V1.3.1 + */ +WMInumber ::= IA5String (SIZE(1..3)) + +/** + * This DE represents the sub cause codes of the @ref CauseCode `wrongWayDriving` . + * + * The value shall be set to: + * - 0 `unavailable` - in case further detailed information on wrong way driving event is unavailable, + * - 1 `wrongLane` - in case vehicle is driving on a lane for which it has no authorization to use, + * - 2 `wrongDirection` - in case vehicle is driving in a direction that it is not allowed, + * - 3-255 - reserved for future usage. + * + * @category: Traffic information + * @revision: V1.3.1 + */ +WrongWayDrivingSubCauseCode ::= INTEGER { + unavailable (0), + wrongLane (1), + wrongDirection (2) +} (0..255) + +/** + * This DE indicates the yaw rate confidence value which represents the estimated accuracy for a yaw rate value with a default confidence level of 95 %. + * If required, the confidence level can be defined by the corresponding standards applying this DE. + * + * The value shall be set to: + * - `0` if the confidence value is equal to or less than 0,01 degree/second, + * - `1` if the confidence value is equal to or less than 0,05 degrees/second or greater than 0,01 degree/second, + * - `2` if the confidence value is equal to or less than 0,1 degree/second or greater than 0,05 degree/second, + * - `3` if the confidence value is equal to or less than 1 degree/second or greater than 0,1 degree/second, + * - `4` if the confidence value is equal to or less than 5 degrees/second or greater than 1 degrees/second, + * - `5` if the confidence value is equal to or less than 10 degrees/second or greater than 5 degrees/second, + * - `6` if the confidence value is equal to or less than 100 degrees/second or greater than 10 degrees/second, + * - `7` if the confidence value is out of range, i.e. greater than 100 degrees/second, + * - `8` if the confidence value is unavailable. + * + * NOTE: The fact that a yaw rate value is received with confidence value set to `unavailable(8)` can be caused by + * several reasons, such as: + * - the sensor cannot deliver the accuracy at the defined confidence level because it is a low-end sensor, + * - the sensor cannot calculate the accuracy due to lack of variables, or + * - there has been a vehicle bus (e.g. CAN bus) error. + * In all 3 cases above, the yaw rate value may be valid and used by the application. + * + * If a yaw rate value is received and its confidence value is set to `outOfRange(7)`, it means that the + * yaw rate value is not valid and therefore cannot be trusted. Such value is not useful the application. + * + * @category: Vehicle information + * @revision: Description revised in V2.1.1 + */ +YawRateConfidence ::= ENUMERATED { + degSec-000-01 (0), + degSec-000-05 (1), + degSec-000-10 (2), + degSec-001-00 (3), + degSec-005-00 (4), + degSec-010-00 (5), + degSec-100-00 (6), + outOfRange (7), + unavailable (8) +} + +/** + * This DE represents the vehicle rotation around z-axis of the coordinate system centred on the centre of mass of the empty-loaded + * vehicle. The leading sign denotes the direction of rotation. + * + * The value shall be provided in the vehicle coordinate system as defined in ISO 8855 [21], clause 2.11. + * + * The value shall be set to: + * - `-32 766` to indicate that the yaw rate is equal to or greater than 327,66 degrees/second to the right, + * - `n` (`n > -32 766` and `n <= 0`) to indicate that the rotation is clockwise (i.e. to the right) and is equal to or less than n x 0,01 degrees/s, + and greater than (n-1) x 0,01 degrees/s, + * - `n` (`n > 0` and `n < 32 766`) to indicate that the rotation is anti-clockwise (i.e. to the left) and is equal to or less than n x 0,01 degrees/s, + and greater than (n-1) x 0,01 degrees/s, + * - `32 766` to indicate that the yaw rate is greater than 327.65 degrees/second to the left, + * - `32 767` to indicate that the information is not available. + * + * The yaw rate value shall be a raw data value, i.e. not filtered, smoothed or otherwise modified. + * The reading instant should be the same as for the vehicle acceleration. + * + * @note: The empty load vehicle is defined in ISO 1176 [8], clause 4.6. + * + * @unit: 0,01 degree per second. + * @category: Vehicle Information + * @revision: Desription revised in V2.1.1 (the meaning of 32766 has changed slightly). +*/ +YawRateValue ::= INTEGER { + negativeOutOfRange (-32766), + positiveOutOfRange (32766), + unavailable (32767) +} (-32766..32767) + +---------------------------------------- +-- Specification of CDD Data Frames: +---------------------------------------- + +/** + * This DF represents an acceleration vector with associated confidence value. + * + * It shall include the following components: + * + * @field polarAcceleration: the representation of the acceleration vector in a polar or cylindrical coordinate system. + * + * @field cartesianAcceleration: the representation of the acceleration vector in a cartesian coordinate system. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +Acceleration3dWithConfidence::= CHOICE { + polarAcceleration AccelerationPolarWithZ, + cartesianAcceleration AccelerationCartesian +} + +/** + * This DF represents an acceleration vector in a polar or cylindrical coordinate system. + + * It shall include the following components: + * + * @field accelerationMagnitude: magnitude of the acceleration vector projected onto the reference plane, with the associated confidence value. + * + * @field accelerationDirection: polar angle of the acceleration vector projected onto the reference plane, with the associated confidence value. + * + * @field zAcceleration: the optional z component of the acceleration vector along the reference axis of the cylindrical coordinate system, with the associated confidence value. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +AccelerationPolarWithZ::= SEQUENCE{ + accelerationMagnitude AccelerationMagnitude, + accelerationDirection CartesianAngle, + zAcceleration AccelerationComponent OPTIONAL +} + +/** + * This DF represents a acceleration vector in a cartesian coordinate system. + + * It shall include the following components: + * + * @field xAcceleration: the x component of the acceleration vector with the associated confidence value. + * + * @field yAcceleration: the y component of the acceleration vector with the associated confidence value. + * + * @field zAcceleration: the optional z component of the acceleration vector with the associated confidence value. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +AccelerationCartesian::= SEQUENCE{ + xAcceleration AccelerationComponent, + yAcceleration AccelerationComponent, + zAcceleration AccelerationComponent OPTIONAL +} + +/** + * This DF represents an acceleration component along with a confidence value. + * + * It shall include the following components: + * + * @field value: the value of the acceleration component which can be estimated as the mean of the current distribution. + * + * @field confidence: the confidence value associated to the provided value. + * + * @category: Kinematic Information + * @revision: Created in V2.1.1 + */ +AccelerationComponent ::= SEQUENCE { + value AccelerationValue, + confidence AccelerationConfidence +} + +/** + * This DF represents information associated to changes in acceleration. + * + * It shall include the following components: + * + * @field accelOrDecel: the indication of an acceleration change. + * + * @field actionDeltaTime: the period over which the acceleration change action is performed. + * + * @category: Kinematic Information + * @revision: Created in V2.1.1 + */ +AccelerationChangeIndication ::= SEQUENCE { + accelOrDecel AccelerationChange, + actionDeltaTime DeltaTimeTenthOfSecond, + ... +} + +/** + * This DF represents the magnitude of the acceleration vector and associated confidence value. + * + * It shall include the following components: + * + * @field accelerationMagnitudeValue: the magnitude of the acceleration vector. + * + * @field accelerationConfidence: the confidence value of the magnitude value. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +AccelerationMagnitude::= SEQUENCE { + accelerationMagnitudeValue AccelerationMagnitudeValue, + accelerationConfidence AccelerationConfidence +} + +/** + * This DF represents an identifier used to describe a protocol action taken by an ITS-S. + * + * It shall include the following components: + * + * @field originatingStationId: Id of the ITS-S that takes the action. + * + * @field sequenceNumber: a sequence number. + * + * @category: Communication information + * @revision: Created in V2.1.1 based on @ref ActionID. + */ +ActionId ::= SEQUENCE { + originatingStationId StationId, + sequenceNumber SequenceNumber +} + +/** + * This DF represents an identifier used to describe a protocol action taken by an ITS-S. + * + * It shall include the following components: + * + * @field originatingStationId: Id of the ITS-S that takes the action. + * + * @field sequenceNumber: a sequence number. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use the @ref ActionId instead. + * @category: Communication information + * @revision: V1.3.1 + */ +ActionID ::= SEQUENCE { + originatingStationId StationID, + sequenceNumber SequenceNumber +} + +/** + * This DF shall contain a list of @ref ActionId. + + * @category: Communication Information + * @revision: Created in V2.1.1 based on ReferenceDenms from DENM Release 1 +*/ +ActionIdList::= SEQUENCE (SIZE(1..8, ...)) OF ActionId + +/** + * This DF provides the altitude and confidence level of an altitude information in a WGS84 coordinate system. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * + * It shall include the following components: + * + * @field altitudeValue: altitude of a geographical point. + * + * @field altitudeConfidence: confidence level of the altitudeValue. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use the @ref AltitudeWithConfidence instead. + * @category: GeoReference information + * @revision: Description revised in V2.1.1 + */ +Altitude ::= SEQUENCE { + altitudeValue AltitudeValue, + altitudeConfidence AltitudeConfidence +} + +/** + * This DE represents a general container for usage in various types of messages. + * + * It shall include the following components: + * + * @field stationType: the type of technical context in which the ITS-S that has generated the message is integrated in. + * + * @field referencePosition: the reference position of the station that has generated the message that contains the basic container. + * + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +BasicContainer ::= SEQUENCE { + stationType TrafficParticipantType, + referencePosition ReferencePositionWithConfidence, + ... +} + +/** + * This DF provides information about the configuration of a road section in terms of lanes using a list of @ref LanePositionAndType . + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ +BasicLaneConfiguration::= SEQUENCE(SIZE(1..16,...)) OF BasicLaneInformation + +/** + * This DF provides basic information about a single lane of a road segment. + * It includes the following components: + * + * @field laneNumber: the number associated to the lane that provides a transversal identification. + * + * @field direction: the direction of traffic flow allowed on the lane. + * + * @field laneWidth: the optional width of the lane. + * + * @field connectingLane: the number of the connecting lane in the next road section, i.e. the number of the lane which the vehicle will use when travelling from one section to the next, + * if it does not actively change lanes. If this component is absent, the lane name number remains the same in the next section. + * + * @field connectingRoadSection: the identifier of the next road section in direction of traffic, that is connecting to the current road section. + * If this component is absent, the connecting road section is the one following the instance where this DF is placed in the @ref RoadConfigurationSectionList. + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ + +BasicLaneInformation::= SEQUENCE{ + laneNumber LanePosition, + direction Direction, + laneWidth LaneWidth OPTIONAL, + connectingLane LanePosition OPTIONAL, + connectingRoadSection RoadSectionId OPTIONAL, + ... +} +((WITH COMPONENTS {..., connectingLane PRESENT}) | + (WITH COMPONENTS {..., connectingLane ABSENT, connectingRoadSection ABSENT})) + +/** + * This DF represents a general Data Frame to describe an angle component along with a confidence value in a cartesian coordinate system. + * + * It shall include the following components: + * + * @field value: The angle value which can be estimated as the mean of the current distribution. + * + * @field confidence: The confidence value associated to the provided value. + * + * @category: Basic information + * @revision: Created in V2.1.1 + */ +CartesianAngle ::= SEQUENCE { + value CartesianAngleValue, + confidence AngleConfidence +} + +/** + * This DF represents an angular velocity component along with a confidence value in a cartesian coordinate system. + * + * It shall include the following components: + * + * @field value: The angular velocity component. + * + * @field confidence: The confidence value associated to the provided value. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +CartesianAngularVelocityComponent ::= SEQUENCE { + value CartesianAngularVelocityComponentValue, + confidence AngularSpeedConfidence +} + +/** + * This DF represents a general Data Frame to describe an angular acceleration component along with a confidence value in a cartesian coordinate system. + * + * It shall include the following components: + * + * @field value: The angular acceleration component value. + * + * @field confidence: The confidence value associated to the provided value. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +CartesianAngularAccelerationComponent ::= SEQUENCE { + value CartesianAngularAccelerationComponentValue, + confidence AngularAccelerationConfidence +} + +/** + * This DF represents a coordinate along with a confidence value in a cartesian reference system. + * + * It shall include the following components: + * + * @field value: the coordinate value, which can be estimated as the mean of the current distribution. + * + * @field confidence: the coordinate confidence value associated to the provided value. + * + * @category: GeoReference information + * @revision: Created in V2.1.1 +*/ +CartesianCoordinateWithConfidence ::= SEQUENCE { + value CartesianCoordinateLarge, + confidence CoordinateConfidence +} + +/** + * This DF represents a position in a two- or three-dimensional cartesian coordinate system. + * + * It shall include the following components: + * + * @field xCoordinate: the X coordinate value. + * + * @field yCoordinate: the Y coordinate value. + * + * @field zCoordinate: the optional Z coordinate value. + * + * @category: GeoReference information + * @revision: Created in V2.1.1 +*/ +CartesianPosition3d::=SEQUENCE{ + xCoordinate CartesianCoordinate, + yCoordinate CartesianCoordinate, + zCoordinate CartesianCoordinate OPTIONAL +} + +/** + * This DF represents a position in a two- or three-dimensional cartesian coordinate system with an associated confidence level for each coordinate. + * + * It shall include the following components: + * + * @field xCoordinate: the X coordinate value with the associated confidence level. + * + * @field yCoordinate: the Y coordinate value with the associated confidence level. + * + * @field zCoordinate: the optional Z coordinate value with the associated confidence level. + * + * @category: GeoReference information + * @revision: Created in V2.1.1 +*/ +CartesianPosition3dWithConfidence::= SEQUENCE{ + xCoordinate CartesianCoordinateWithConfidence, + yCoordinate CartesianCoordinateWithConfidence, + zCoordinate CartesianCoordinateWithConfidence OPTIONAL +} + +/** + * This DF is a representation of the cause code value of a traffic event. + * + * It shall include the following components: + * + * @field causeCode: the main cause of a detected event. + * + * @field subCauseCode: the subordinate cause of a detected event. + * + * The semantics of the entire DF are completely defined by the component causeCode. The interpretation of the subCauseCode may + * provide additional information that is not strictly necessary to understand the causeCode itself, and is therefore optional. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use the @ref CauseCodeV2 instead. + * + * @category: Traffic information + * @revision: Editorial update in V2.1.1 + */ +CauseCode ::= SEQUENCE { + causeCode CauseCodeType, + subCauseCode SubCauseCodeType, + ... +} + +/** + * This DF is a representation of the cause code value and associated sub cause code value of a traffic event. + * + * The following options are available: + * - 0 - reserved for future use, + * - 1 - `trafficCondition1` - in case the type of event is an abnormal traffic condition, + * - 2 - `accident2` - in case the type of event is a road accident, + * - 3 - `roadworks3` - in case the type of event is roadwork, + * - 4 - reserved for future usage, + * - 5 - `impassability5` - in case the type of event is unmanaged road blocking, referring to any + * blocking of a road, partial or total, which has not been adequately secured and signposted, + * - 6 - `adverseWeatherCondition-Adhesion6` - in case the type of event is low adhesion, + * - 7 - `aquaplaning7` - danger of aquaplaning on the road, + * - 8 - reserved for future usage, + * - 9 - `hazardousLocation-SurfaceCondition9` - in case the type of event is abnormal road surface condition, + * - 10 - `hazardousLocation-ObstacleOnTheRoad10` - in case the type of event is obstacle on the road, + * - 11 - `hazardousLocation-AnimalOnTheRoad11` - in case the type of event is animal on the road, + * - 12 - `humanPresenceOnTheRoad` - in case the type of event is presence of human vulnerable road user on the road, + * - 13 - reserved for future usage, + * - 14 - `wrongWayDriving14` - in case the type of the event is vehicle driving in wrong way, + * - 15 - `rescueAndRecoveryWorkInProgress15` - in case the type of event is rescue and recovery work for accident or for a road hazard in progress, + * - 16 - reserved for future usage, + * - 17 - `adverseWeatherCondition-ExtremeWeatherCondition17` - in case the type of event is extreme weather condition, + * - 18 - `adverseWeatherCondition-Visibility18` - in case the type of event is low visibility, + * - 19 - `adverseWeatherCondition-Precipitation19` - in case the type of event is precipitation, + * - 20 - `violence20` - in case the the type of event is human violence on or near the road, + * - 21-25 - reserved for future usage, + * - 26 - `slowVehicle26` - in case the type of event is slow vehicle driving on the road, + * - 27 - `dangerousEndOfQueue27` - in case the type of event is dangerous end of vehicle queue, + * - 28 - `publicTransportVehicleApproaching - in case the type of event is a public transport vehicle approaching, with a priority defined by applicable traffic regulations, + * - 29-90 - are reserved for future usage, + * - 91 - `vehicleBreakdown91` - in case the type of event is break down vehicle on the road, + * - 92 - `postCrash92` - in case the type of event is a detected crash, + * - 93 - `humanProblem93` - in case the type of event is human health problem in vehicles involved in traffic, + * - 94 - `stationaryVehicle94` - in case the type of event is stationary vehicle, + * - 95 - `emergencyVehicleApproaching95` - in case the type of event is an approaching vehicle operating on a mission for which the + applicable traffic regulations provide it with defined priority rights in traffic. + * - 96 - `hazardousLocation-DangerousCurve96` - in case the type of event is dangerous curve, + * - 97 - `collisionRisk97` - in case the type of event is a collision risk, + * - 98 - `signalViolation98` - in case the type of event is signal violation, + * - 99 - `dangerousSituation99` - in case the type of event is dangerous situation in which autonomous safety system in vehicle + * is activated, + * - 100 - `railwayLevelCrossing100` - in case the type of event is a railway level crossing. + * - 101-255 - are reserved for future usage. + * + * @note: this DF is defined for use as part of CauseCodeV2. It is recommended to use CauseCodeV2. + * @category: Traffic information + * @revision: Created in V2.1.1, the type of impassability5 changed to ImpassabilitySubCauseCode in V2.2.1, value 28 added in V2.2.1, definition of value 12 and 95 changed in V2.2.1 + */ +CauseCodeChoice::= CHOICE { + reserved0 SubCauseCodeType, + trafficCondition1 TrafficConditionSubCauseCode, + accident2 AccidentSubCauseCode, + roadworks3 RoadworksSubCauseCode, + reserved4 SubCauseCodeType, + impassability5 ImpassabilitySubCauseCode, + adverseWeatherCondition-Adhesion6 AdverseWeatherCondition-AdhesionSubCauseCode, + aquaplaning7 SubCauseCodeType, + reserved8 SubCauseCodeType, + hazardousLocation-SurfaceCondition9 HazardousLocation-SurfaceConditionSubCauseCode, + hazardousLocation-ObstacleOnTheRoad10 HazardousLocation-ObstacleOnTheRoadSubCauseCode, + hazardousLocation-AnimalOnTheRoad11 HazardousLocation-AnimalOnTheRoadSubCauseCode, + humanPresenceOnTheRoad12 HumanPresenceOnTheRoadSubCauseCode, + reserved13 SubCauseCodeType, + wrongWayDriving14 WrongWayDrivingSubCauseCode, + rescueAndRecoveryWorkInProgress15 RescueAndRecoveryWorkInProgressSubCauseCode, + reserved16 SubCauseCodeType, + adverseWeatherCondition-ExtremeWeatherCondition17 AdverseWeatherCondition-ExtremeWeatherConditionSubCauseCode, + adverseWeatherCondition-Visibility18 AdverseWeatherCondition-VisibilitySubCauseCode, + adverseWeatherCondition-Precipitation19 AdverseWeatherCondition-PrecipitationSubCauseCode, + violence20 SubCauseCodeType, + reserved21 SubCauseCodeType, + reserved22 SubCauseCodeType, + reserved23 SubCauseCodeType, + reserved24 SubCauseCodeType, + reserved25 SubCauseCodeType, + slowVehicle26 SlowVehicleSubCauseCode, + dangerousEndOfQueue27 DangerousEndOfQueueSubCauseCode, + publicTransportVehicleApproaching28 SubCauseCodeType, + reserved29 SubCauseCodeType, + reserved30 SubCauseCodeType, + reserved31 SubCauseCodeType, + reserved32 SubCauseCodeType, + reserved33 SubCauseCodeType, + reserved34 SubCauseCodeType, + reserved35 SubCauseCodeType, + reserved36 SubCauseCodeType, + reserved37 SubCauseCodeType, + reserved38 SubCauseCodeType, + reserved39 SubCauseCodeType, + reserved40 SubCauseCodeType, + reserved41 SubCauseCodeType, + dontPanic42 SubCauseCodeType, + reserved43 SubCauseCodeType, + reserved44 SubCauseCodeType, + reserved45 SubCauseCodeType, + reserved46 SubCauseCodeType, + reserved47 SubCauseCodeType, + reserved48 SubCauseCodeType, + reserved49 SubCauseCodeType, + reserved50 SubCauseCodeType, + reserved51 SubCauseCodeType, + reserved52 SubCauseCodeType, + reserved53 SubCauseCodeType, + reserved54 SubCauseCodeType, + reserved55 SubCauseCodeType, + reserved56 SubCauseCodeType, + reserved57 SubCauseCodeType, + reserved58 SubCauseCodeType, + reserved59 SubCauseCodeType, + reserved60 SubCauseCodeType, + reserved61 SubCauseCodeType, + reserved62 SubCauseCodeType, + reserved63 SubCauseCodeType, + reserved64 SubCauseCodeType, + reserved65 SubCauseCodeType, + reserved66 SubCauseCodeType, + reserved67 SubCauseCodeType, + reserved68 SubCauseCodeType, + reserved69 SubCauseCodeType, + reserved70 SubCauseCodeType, + reserved71 SubCauseCodeType, + reserved72 SubCauseCodeType, + reserved73 SubCauseCodeType, + reserved74 SubCauseCodeType, + reserved75 SubCauseCodeType, + reserved76 SubCauseCodeType, + reserved77 SubCauseCodeType, + reserved78 SubCauseCodeType, + reserved79 SubCauseCodeType, + reserved80 SubCauseCodeType, + reserved81 SubCauseCodeType, + reserved82 SubCauseCodeType, + reserved83 SubCauseCodeType, + reserved84 SubCauseCodeType, + reserved85 SubCauseCodeType, + reserved86 SubCauseCodeType, + reserved87 SubCauseCodeType, + reserved88 SubCauseCodeType, + reserved89 SubCauseCodeType, + reserved90 SubCauseCodeType, + vehicleBreakdown91 VehicleBreakdownSubCauseCode, + postCrash92 PostCrashSubCauseCode, + humanProblem93 HumanProblemSubCauseCode, + stationaryVehicle94 StationaryVehicleSubCauseCode, + emergencyVehicleApproaching95 EmergencyVehicleApproachingSubCauseCode, + hazardousLocation-DangerousCurve96 HazardousLocation-DangerousCurveSubCauseCode, + collisionRisk97 CollisionRiskSubCauseCode, + signalViolation98 SignalViolationSubCauseCode, + dangerousSituation99 DangerousSituationSubCauseCode, + railwayLevelCrossing100 RailwayLevelCrossingSubCauseCode, + reserved101 SubCauseCodeType, + reserved102 SubCauseCodeType, + reserved103 SubCauseCodeType, + reserved104 SubCauseCodeType, + reserved105 SubCauseCodeType, + reserved106 SubCauseCodeType, + reserved107 SubCauseCodeType, + reserved108 SubCauseCodeType, + reserved109 SubCauseCodeType, + reserved110 SubCauseCodeType, + reserved111 SubCauseCodeType, + reserved112 SubCauseCodeType, + reserved113 SubCauseCodeType, + reserved114 SubCauseCodeType, + reserved115 SubCauseCodeType, + reserved116 SubCauseCodeType, + reserved117 SubCauseCodeType, + reserved118 SubCauseCodeType, + reserved119 SubCauseCodeType, + reserved120 SubCauseCodeType, + reserved121 SubCauseCodeType, + reserved122 SubCauseCodeType, + reserved123 SubCauseCodeType, + reserved124 SubCauseCodeType, + reserved125 SubCauseCodeType, + reserved126 SubCauseCodeType, + reserved127 SubCauseCodeType, + reserved128 SubCauseCodeType + } + +/** + * This DF is an alternative representation of the cause code value of a traffic event. + * + * It shall include the following components: + * + * @field ccAndScc: the main cause of a detected event. Each entry is of a different type and represents the sub cause code. + + * The semantics of the entire DF are completely defined by the choice value which represents the cause code value. + * The interpretation of the sub cause code value may provide additional information that is not strictly necessary to understand + * the cause code itself, and is therefore optional. + * + * @category: Traffic information + * @revision: Created in V2.1.1, description amended in V2.2.1 + */ +CauseCodeV2 ::= SEQUENCE { + ccAndScc CauseCodeChoice, + ... +} + +/** + * The DF describes the position of a CEN DSRC road side equipment. + * + * It shall include the following components: + * + * @field protectedZoneLatitude: the latitude of the CEN DSRC road side equipment. + * + * @field protectedZoneLongitude: the latitude of the CEN DSRC road side equipment. + * + * @field cenDsrcTollingZoneID: the optional ID of the CEN DSRC road side equipment. + * + * @category: Infrastructure information, Communication information + * @revision: revised in V2.1.1 (cenDsrcTollingZoneId is directly of type ProtectedZoneId) + */ +CenDsrcTollingZone ::= SEQUENCE { + protectedZoneLatitude Latitude, + protectedZoneLongitude Longitude, + cenDsrcTollingZoneId ProtectedZoneId OPTIONAL, + ... +} + +/** + * + * This DF represents the shape of a circular area or a right cylinder that is centred on the shape's reference point. + * + * It shall include the following components: + * + * @field shapeReferencePoint: optional reference point that represents the centre of the circle, relative to an externally specified reference position. + * If this component is absent, the externally specified reference position represents the shape's reference point. + * + * @field radius: the radius of the circular area. + * + * @field height: the optional height, present if the shape is a right cylinder extending in the positive z-axis. + * + * + * @category: GeoReference information + * @revision: Created in V2.1.1 + */ +CircularShape ::= SEQUENCE { + shapeReferencePoint CartesianPosition3d OPTIONAL, + radius StandardLength12b, + height StandardLength12b OPTIONAL +} + +/** + * This DF indicates the opening/closure status of the lanes of a carriageway. + * + * It shall include the following components: + * + * @field innerhardShoulderStatus: this information is optional and shall be included if an inner hard shoulder is present and the information is known. + * It indicates the open/closing status of inner hard shoulder lanes. + * + * @field outerhardShoulderStatus: this information is optional and shall be included if an outer hard shoulder is present and the information is known. + * It indicates the open/closing status of outer hard shoulder lanes. + * + * @field drivingLaneStatus: this information is optional and shall be included if the information is known. + * It indicates the open/closing status of driving lanes. + * For carriageways with more than 13 driving lanes, the drivingLaneStatus component shall not be present. + * + * @category: Infrastructure information, Road topology information + * @revision: Description revised in V2.1.1 + */ +ClosedLanes ::= SEQUENCE { + innerhardShoulderStatus HardShoulderStatus OPTIONAL, + outerhardShoulderStatus HardShoulderStatus OPTIONAL, + drivingLaneStatus DrivingLaneStatus OPTIONAL, + ... +} + +/** + * This DF provides information about the breakup of a cluster. + * + * It shall include the following components: + * + * @field clusterBreakupReason: indicates the reason for breakup. + * + * @field breakupTime: indicates the time of breakup. + * + * @category: Cluster Information + * @revision: Created in V2.1.1 + */ +ClusterBreakupInfo ::= SEQUENCE { + clusterBreakupReason ClusterBreakupReason, + breakupTime DeltaTimeQuarterSecond, + ... +} + +/** + * This DF provides information about the joining of a cluster. + * + * It shall include the following components: + * + * @field clusterId: indicates the identifier of the cluster. + * + * @field joinTime: indicates the time of joining. + * + * @category: Cluster Information + * @revision: Created in V2.1.1 + */ +ClusterJoinInfo ::= SEQUENCE { + clusterId Identifier1B, + joinTime DeltaTimeQuarterSecond, + ... +} + +/** + * The DF provides information about the leaving of a cluster. + * + * It shall include the following components: + * + * @field clusterId: indicates the cluster. + * + * @field clusterLeaveReason: indicates the reason for leaving. + * + * @category: Cluster Information + * @revision: Created in V2.1.1 + */ +ClusterLeaveInfo ::= SEQUENCE { + clusterId Identifier1B, + clusterLeaveReason ClusterLeaveReason, + ... +} + +/** +* This DF shall contain a list of @ref ConfidenceLevel. +* +* @category: Basic information +* @revision: created in V2.3.1 +*/ +ConfidenceLevels ::= SEQUENCE (SIZE (1..32,...)) OF ConfidenceLevel + +/** + * This DF represents a column of a lower triangular positive semi-definite matrix and consists of a list of correlation cell values ordered by rows. + * Given a matrix "A" of size n x n, the number of columns to be included in the lower triangular matrix is k=n-1. + * Each column "i" of the lower triangular matrix then contains k-(i-1) values (ordered by rows from 1 to n-1), where "i" refers to the column number count + * starting at 1 from the left. + * + * @category: Sensing Information + * @revision: Created in V2.1.1 +*/ +CorrelationColumn ::= SEQUENCE SIZE (1..13,...) OF CorrelationCellValue + +/** + * This DF represents the curvature of the vehicle trajectory and the associated confidence value. + * The curvature detected by a vehicle represents the curvature of actual vehicle trajectory. + * + * It shall include the following components: + * + * @field curvatureValue: Detected curvature of the vehicle trajectory. + * + * @field curvatureConfidence: along with a confidence value of the curvature value with a predefined confidence level. + * + * @category: Vehicle information + * @revision: Description revised in V2.1.1 + */ +Curvature ::= SEQUENCE { + curvatureValue CurvatureValue, + curvatureConfidence CurvatureConfidence +} + +/** + * This DF provides a description of dangerous goods being carried by a heavy vehicle. + * + * It shall include the following components: + * + * @field dangerousGoodsType: Type of dangerous goods. + * + * @field unNumber: a 4-digit number that identifies the substance of the dangerous goods as specified in + * United Nations Recommendations on the Transport of Dangerous Goods - Model Regulations [4], + * + * @field elevatedTemperature: whether the carried dangerous goods are transported at high temperature. + * If yes, the value shall be set to TRUE, + * + * @field tunnelsRestricted: whether the heavy vehicle carrying dangerous goods is restricted to enter tunnels. + * If yes, the value shall be set to TRUE, + * + * @field limitedQuantity: whether the carried dangerous goods are packed with limited quantity. + * If yes, the value shall be set to TRUE, + * + * @field emergencyActionCode: physical signage placard at the vehicle that carries information on how an emergency + * service should deal with an incident. This component is optional; it shall be present if the information is available. + * + * @field phoneNumber: contact phone number of assistance service in case of incident or accident. + * This component is optional, it shall be present if the information is available. + * + * @field companyName: name of company that manages the transportation of the dangerous goods. + * This component is optional; it shall be present if the information is available. + * + * @category Vehicle information + * @revision: V1.3.1 + */ +DangerousGoodsExtended ::= SEQUENCE { + dangerousGoodsType DangerousGoodsBasic, + unNumber INTEGER (0..9999), + elevatedTemperature BOOLEAN, + tunnelsRestricted BOOLEAN, + limitedQuantity BOOLEAN, + emergencyActionCode IA5String (SIZE (1..24)) OPTIONAL, + phoneNumber PhoneNumber OPTIONAL, + companyName UTF8String (SIZE (1..24)) OPTIONAL, + ... +} + +/** +* This DF defines a geographical point position as a 2 dimensional offset position to a geographical reference point. +* +* It shall include the following components: +* +* @field deltaLatitude: A delta latitude offset with regards to the latitude value of the reference position. +* +* @field deltaLongitude: A delta longitude offset with regards to the longitude value of the reference position. +* +* @category: GeoReference information +* @revision: created in V2.3.1 based on ISO TS 19321 +*/ +DeltaPosition ::= SEQUENCE{ + deltaLatitude DeltaLatitude, + deltaLongitude DeltaLongitude +} + +/** +* This DF shall contain a list of @ref DeltaPosition. +* +* @category: GeoReference information +* @revision: created in V2.3.1 based on ISO TS 19321 (DF DeltaPosition) +*/ +DeltaPositions ::= SEQUENCE (SIZE (1..32,...,33..100)) OF DeltaPosition + +/** + * This DF defines a geographical point position as a 3 dimensional offset position to a geographical reference point. + * + * It shall include the following components: + * + * @field deltaLatitude: A delta latitude offset with regards to the latitude value of the reference position. + * + * @field deltaLongitude: A delta longitude offset with regards to the longitude value of the reference position. + * + * @field deltaAltitude: A delta altitude offset with regards to the altitude value of the reference position. + * + * @category: GeoReference information + * @revision: V1.3.1 + */ +DeltaReferencePosition ::= SEQUENCE { + deltaLatitude DeltaLatitude, + deltaLongitude DeltaLongitude, + deltaAltitude DeltaAltitude +} + +/** +* This DF shall contain a list of @ref DeltaReferencePosition. +* +* @category: GeoReference information +* @revision: created in V2.3.1 based on ISO TS 19321 (DF DeltaReferencePositions) +*/ +DeltaReferencePositions ::= SEQUENCE (SIZE (1..32,...,33..100)) OF DeltaReferencePosition + +/** + * This DF represents a portion of digital map. It shall contain a list of waypoints @ref ReferencePosition. + * + * @category: GeoReference information + * @revision: V1.3.1 + */ +DigitalMap ::= SEQUENCE (SIZE(1..256)) OF ReferencePosition + +/** + * + * This DF represents the shape of an elliptical area or right elliptical cylinder that is centred + * on the shape's reference point defined outside of the context of this DF and oriented w.r.t. a + * cartesian coordinate system defined outside of the context of this DF. + * + * It shall include the following components: + * + * @field shapeReferencePoint: optional reference point which represents the centre of the ellipse, + * relative to an externally specified reference position. If this component is absent, the + * externally specified reference position represents the shape's reference point. + * + * @field semiMajorAxisLength: half length of the major axis of the ellipse located in the X-Y Plane. + * + * @field semiMinorAxisLength: half length of the minor axis of the ellipse located in the X-Y Plane. + * + * @field orientation: the optional orientation of the major axis of the ellipse, measured with + * positive values turning around the z-axis using the right-hand rule, starting from the X-axis. + * + * @field height: the optional height, present if the shape is a right elliptical cylinder extending + * in the positive Z-axis. + * + * @category: GeoReference information + * @revision: Created in V2.1.1, the type of the field orientation changed and the description revised in V2.2.1 +*/ + +EllipticalShape ::= SEQUENCE { + shapeReferencePoint CartesianPosition3d OPTIONAL, + semiMajorAxisLength StandardLength12b, + semiMinorAxisLength StandardLength12b, + orientation CartesianAngleValue OPTIONAL, + height StandardLength12b OPTIONAL +} + +/** + * This DF represents the Euler angles which describe the orientation of an object bounding box in a Cartesian coordinate system with an associated confidence level for each angle. + * + * It shall include the following components: + * + * @field zAngle: z-angle of object bounding box at the time of measurement, with the associated confidence. + * The angle is measured with positive values considering the object orientation turning around the z-axis using the right-hand rule, starting from the x-axis. + * This extrinsic rotation shall be applied around the centre point of the object bounding box before all other rotations. + * + * @field yAngle: optional y-angle of object bounding box at the time of measurement, with the associated confidence. + * The angle is measured with positive values considering the object orientation turning around the y-axis using the right-hand rule, starting from the z-axis. + * This extrinsic rotation shall be applied around the centre point of the object bounding box after the rotation by zAngle and before the rotation by xAngle. + * + * @field xAngle: optional x-angle of object bounding box at the time of measurement, with the associated confidence. + * The angle is measured with positive values considering the object orientation turning around the x-axis using the right-hand rule, starting from the z-axis. + * This extrinsic rotation shall be applied around the centre point of the object bounding box after all other rotations. + * + * @category: Basic information + * @revision: Created in V2.1.1 +*/ +EulerAnglesWithConfidence ::= SEQUENCE { + zAngle CartesianAngle, + yAngle CartesianAngle OPTIONAL, + xAngle CartesianAngle OPTIONAL +} + +/** + * + * This DF represents a vehicle category according to the UNECE/TRANS/WP.29/78/Rev.4 [16]. + * The following options are available: + * + * @field euVehicleCategoryL: indicates a vehicle in the L category. + * + * @field euVehicleCategoryM: indicates a vehicle in the M category. + * + * @field euVehicleCategoryN: indicates a vehicle in the N category. + * + * @field euVehicleCategoryO: indicates a vehicle in the O category. + * + * @field euVehicleCategoryT: indicates a vehicle in the T category. + * + * @field euVehicleCategoryG: indicates a vehicle in the G category. + * + * @category: Vehicle information + * @revision: Created in V2.1.1 +*/ +EuVehicleCategoryCode ::= CHOICE { + euVehicleCategoryL EuVehicleCategoryL, + euVehicleCategoryM EuVehicleCategoryM, + euVehicleCategoryN EuVehicleCategoryN, + euVehicleCategoryO EuVehicleCategoryO, + euVehicleCategoryT NULL, + euVehicleCategoryG NULL +} + +/** + * The DF shall contain a list of @ref EventPoint. + * + * The eventPosition of each @ref EventPoint is defined with respect to the previous @ref EventPoint in the list. + * Except for the first @ref EventPoint which is defined with respect to a position outside of the context of this DF. + * + * @category: GeoReference information, Traffic information + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use the @ref EventZone instead. + * @revision: Generalized the semantics in V2.1.1 + */ +EventHistory::= SEQUENCE (SIZE(1..23)) OF EventPoint + +/** + * This DF provides information related to an event at a defined position. + * + * It shall include the following components: + * + * @field eventPosition: offset position of a detected event point to a defined position. + * + * @field eventDeltaTime: optional time travelled by the detecting ITS-S since the previous detected event point. + * + * @field informationQuality: Information quality of the detection for this event point. + * + * @category: GeoReference information, Traffic information + * @revision: generalized the semantics in V2.1.1 + */ +EventPoint ::= SEQUENCE { + eventPosition DeltaReferencePosition, + eventDeltaTime PathDeltaTime OPTIONAL, + informationQuality InformationQuality +} + +/** + * The DF shall contain a list of @ref EventPoint, where all @ref EventPoint either contain the COMPONENT eventDeltaTime + * or do not contain the COMPONENT eventDeltaTime. + * + * The eventPosition of each @ref EventPoint is defined with respect to the previous @ref EventPoint in the list. + * Except for the first @ref EventPoint which is defined with respect to a position outside of the context of this DF. + * + * @category: GeoReference information, Traffic information + * @revision: created in V2.1.1 based on EventHistory + */ +EventZone::= EventHistory + ((WITH COMPONENT (WITH COMPONENTS {..., eventDeltaTime PRESENT})) | + (WITH COMPONENT (WITH COMPONENTS {..., eventDeltaTime ABSENT}))) + +/** + * This DF indicates a geographical position. + * + * It shall include the following components: + * + * @field latitude: the latitude of the geographical position. + * + * @field longitude: the longitude of the geographical position. + * + * @field altitude: the altitude of the geographical position with default value unavailable. + * +*/ +GeoPosition::= SEQUENCE{ + latitude Latitude, + longitude Longitude, + altitude AltitudeValue DEFAULT unavailable +} + +/** +* This DE indicates a geographical position with altitude. +* +* It shall include the following components: +* +* @field latitude: the latitude of the geographical position. +* +* @field longitude: the longitude of the geographical position. +* +* @field altitude: the altitude of the geographical position. +* +* @category: GeoReference information +* @revision: created in V2.3.1 based on ISO TS 19321 (DF AbsolutePositionWAltitude) +*/ +GeoPositionWAltitude ::= SEQUENCE{ + latitude Latitude, + longitude Longitude, + altitude Altitude +} + +/** +* This DF shall contain a list of @ref AbsolutePositionWAltitude. +* +* @category: GeoReference information +* @revision: created in V2.3.1 based on ISO TS 19321 (DF AbsolutePositionsWAltitude) +*/ +GeoPositionsWAltitude ::= SEQUENCE (SIZE (1..8,...)) OF GeoPositionWAltitude + +/** +* This DF indicates a geographical position without altitude. +* +* It shall include the following components: +* +* @field latitude: the latitude of the geographical position. +* +* @field longitude: the longitude of the geographical position. +* +* @category: GeoReference information +* @revision: created in V2.3.1 based on ISO TS 19321 (DF AbsolutePosition) +*/ +GeoPositionWoAltitude ::= SEQUENCE{ + latitude Latitude, + longitude Longitude +} + +/** +* This DF shall contain a list of @ref GeoPositionWoAltitude. +* +* @category: GeoReference information +* @revision: created in V2.3.1 based on ISO TS 19321 (AbsolutePositions) +*/ +GeoPositionsWoAltitude ::= SEQUENCE (SIZE (1..8,...)) OF GeoPositionWoAltitude + +/** + * This DF represents the top-level DF to represent a lane position. A lane position is a transversal position on the carriageway at a specific longitudinal position, in resolution of lanes of the carriageway. + * + * @note: This DF is the most general way to represent a lane position: it provides a complete set of information regarding a transversal (dimensionless) position on the carriageway at a specific + * reference position, i.e. it provides different options and synonyms to represent the lane at which the reference position (the point) is located. A confidence is used to describe the probability + * that the object is located in the provided lane. The dimension of the object or extension of an area are not considered: See @ref OccupiedLanesWithConfidence for describing the occupation of lanes, + * where the dimensions of an object or the extension of an area is considered. + * + * It shall include the following components: + * + * @field lanePositionBased: lane position information for a defined reference position. + * + * @field mapBased: optional lane position information described in the context of a MAPEM as specified in ETSI TS 103 301 [15]. + * If present, it shall describe the same reference position using the lane identification in the MAPEM. This component can be used only if a MAPEM is available for the reference position + * (e.g. on an intersection): In this case it is used as a synonym to the mandatory component lanePositionBased. + * + * @field confidence: confidence information for expressing the probability that the object is located at the indicated lane. + * If the value of the component lanePositionBased is generated directly from the absolute reference position and reference topology information, + * no sensor shall be indicated in the component usedDetectionInformation of the @ref MetaInformation. + * + * @category: Road Topology information + * @revision: newly created in V2.2.1. The previous DF GeneralizedLanePosition is now renamed to @ref LanePositionOptions. + */ +GeneralizedLanePosition ::= SEQUENCE { + lanePositionBased LanePositionOptions, + mapBased MapPosition OPTIONAL, + confidence MetaInformation, + ... +} + +/** + * This DF represents transversal position information with respect to the road, at an externally defined reference position. It shall contain a set of up to `4` @ref GeneralizedLanePosition. + * Multiple entries can be used to describe several lane positions with the associated confidence, in cases where the reference position cannot be mapped to a single lane. + * + * @category: Road Topology information + * @revision: Created in V2.2.1 + */ +GeneralizedLanePositions ::= SEQUENCE (SIZE(1..4)) OF GeneralizedLanePosition + +/** + * This DF represents the Heading in a WGS84 co-ordinates system. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * + * It shall include the following components: + * + * @field headingValue: the heading value. + * + * @field headingConfidence: the confidence value of the heading value with a predefined confidence level. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use the @ref Wgs84Angle instead. + * @category: Kinematic Information + * @revision: Description revised in V2.1.1 + */ +Heading ::= SEQUENCE { + headingValue HeadingValue, + headingConfidence HeadingConfidence +} + + +/** + * This DF provides information associated to heading change indicators such as a change of direction. + * + * It shall include the following components: + * + * @field direction: the direction of heading change value. + * + * @field actionDeltaTime: the period over which a direction change action is performed. + * + * @category: Kinematic Information + * @revision: created in V2.1.1 + */ +HeadingChangeIndication ::= SEQUENCE { + direction TurningDirection, + actionDeltaTime DeltaTimeTenthOfSecond, + ... +} + +/** + * This DF represents a frequency channel + * + * It shall include the following components: + * + * @field centreFrequency: the centre frequency of the channel in 10^(exp+2) Hz (where exp is exponent) + * + * @field channelWidth: width of the channel in 10^exp Hz (where exp is exponent) + * + * @field exponent: exponent of the power of 10 used in the calculation of the components above. + * + * @category: Communication information + * @revision: created in V2.1.1 +*/ +InterferenceManagementChannel ::= SEQUENCE { + centreFrequency INTEGER (1 .. 99999), + channelWidth INTEGER (0 .. 9999), + exponent INTEGER (0 .. 15) +} + +/** + * + * This DF represents a zone inside which the ITS communication should be restricted in order to manage interference. + * + * It shall include the following components: + * + * @field zoneDefinition: contains the geographical definition of the zone. + * + * @field managementInfo: contains interference management information applicable in the zone defined in the component zoneDefinition. + * + * @category: Communication information + * @revision: created in V2.1.1 + */ +InterferenceManagementZone ::= SEQUENCE { + zoneDefinition InterferenceManagementZoneDefinition, + managementInfo InterferenceManagementInfo +} + +/** + * This DF represents the geographical definition of the zone where band sharing occurs. + * + * It shall include the following components: + * + * @field interferenceManagementZoneLatitude: Latitude of the centre point of the interference management zone. + * + * @field interferenceManagementZoneLongitude: Longitude of the centre point of the interference management zone. + * + * @field interferenceManagementZoneId: optional identification of the interference management zone. + * + * @field interferenceManagementZoneShape: shape of the interference management zone placed at the centre point. + * + * @category: Communication information + * @revision: created in V2.1.1 + */ +InterferenceManagementZoneDefinition::= SEQUENCE{ + interferenceManagementZoneLatitude Latitude, + interferenceManagementZoneLongitude Longitude, + interferenceManagementZoneId ProtectedZoneId OPTIONAL, + interferenceManagementZoneShape Shape + (WITH COMPONENTS{..., radial ABSENT, radialShapes ABSENT}) OPTIONAL, + ... +} + +/** + * This DF shall contain a list of up to 16 definitions containing interference management information, per affected frequency channels. + * + * @category: Communication information. + * @revision: created in V2.1.1 + */ +InterferenceManagementInfo::= SEQUENCE (SIZE(1..16,...)) OF InterferenceManagementInfoPerChannel + + +/** + * This DF contains interference management information for one affected frequency channel. + * + * It shall include the following components: + * + * @field interferenceManagementChannel: frequency channel for which the zone should be applied interference management + * + * @field interferenceManagementZoneType: type of the interference management zone. + * + * @field interferenceManagementMitigationType: optional type of the mitigation to be used in the interference management zone. + * In the case where no mitigation should be applied by the ITS-S, this is indicated by the field interferenceManagementMitigationType being absent. + * + * @field expiryTime: optional time at which the validity of the interference management communication zone will expire. + * This component is present when the interference management is temporarily valid + * + * @category: Communication information + * @revision: created in V2.1.1 + */ +InterferenceManagementInfoPerChannel ::= SEQUENCE { + interferenceManagementChannel InterferenceManagementChannel, + interferenceManagementZoneType InterferenceManagementZoneType, + interferenceManagementMitigationType MitigationForTechnologies OPTIONAL, + expiryTime TimestampIts OPTIONAL, + ... +} + +/** + * This DF shall contain a list of up to 16 interference management zones. + * + * **EXAMPLE**: An interference management communication zone may be defined around a CEN DSRC road side equipment or an urban rail operational area. + * + * @category: Communication information + * @revision: created in V2.1.1 + */ +InterferenceManagementZones ::= SEQUENCE (SIZE(1..16), ...) OF InterferenceManagementZone + +/** + * This DF represents a unique id for an intersection, in accordance with ETSI TS 103 301 [15]. + * + * It shall include the following components: + * + * @field region: the optional identifier of the entity that is responsible for the region in which the intersection is placed. + * It is the duty of that entity to guarantee that the @ref Id is unique within the region. + * + * @field id: the identifier of the intersection + * + * @note: when the component region is present, the IntersectionReferenceId is guaranteed to be globally unique. + * @category: Road topology information + * @revision: created in V2.1.1 + */ +IntersectionReferenceId ::= SEQUENCE { + region Identifier2B OPTIONAL, + id Identifier2B +} + +/** + * This DF shall contain a list of waypoints @ref ReferencePosition. + * + * @category: GeoReference information + * @revision: Editorial update in V2.1.1 + */ +ItineraryPath ::= SEQUENCE SIZE(1..40) OF ReferencePosition + +/** + * This DF represents a common message header for application and facilities layer messages. + * It is included at the beginning of an ITS message as the message header. + * + * It shall include the following components: + * + * @field protocolVersion: version of the ITS message. + * + * @field messageId: type of the ITS message. + * + * @field stationId: the identifier of the ITS-S that generated the ITS message. + * + * @category: Communication information + * @revision: update in V2.1.1: messageID and stationID changed to messageId and stationId; messageId is of type MessageId. + */ +ItsPduHeader ::= SEQUENCE { + protocolVersion OrdinalNumber1B, + messageId MessageId, + stationId StationId +} + +/** + * This DF provides the reference to the information contained in a IVIM according to ETSI TS 103 301 [15]. + * + * It shall include the following components: + * + * @field serviceProviderId: identifier of the organization that provided the IVIM. + * + * @field iviIdentificationNumber: identifier of the IVIM, as assigned by the organization identified in serviceProviderId. + * + * @category: Communication information + * @revision: Created in V2.2.1 + */ +IvimReference::= SEQUENCE { + serviceProviderId Provider, + iviIdentificationNumber IviIdentificationNumber +} + +/** + * This DF shall contain a list of @ref IvimReference. + * + * @category: Communication information + * @revision: Created in V2.2.1 +*/ +IvimReferences::= SEQUENCE (SIZE(1..8,...)) OF IvimReference + +/** + * This DF indicates a transversal position in resolution of lanes and other associated details. + * + * It shall include the following components: + * + * @field transversalPosition: the transversal position. + * + * @field laneType: the type of the lane identified in the component transversalPosition. By default set to `traffic`. + * + * @field direction: the traffic direction for the lane position relative to a defined reference direction. By default set to `sameDirection`, i.e. following the reference direction. + * + * @category Road topology information + * @revision: direction added in V2.2.1 + */ +LanePositionAndType::= SEQUENCE { + transversalPosition LanePosition, + laneType LaneType DEFAULT traffic, + direction Direction DEFAULT sameDirection, + ... +} + +/** + * This DF represents a set of options to describe a lane position and is the second level DF to represent a lane position. The top-level DFs are @ref GeneralizedLanePosition or @ref OccupiedLanesWithConfidence. + * A lane position is a transversal position on the carriageway at a specific longitudinal position, in resolution of lanes of the carriageway. + * + * The following options are available: + * + * @field simplelanePosition: a single lane position without any additional context information. + * + * @field simpleLaneType: a lane type, to be used when the lane position is unknown but the type of lane is known. This can be used in scenarios where a certain confidence about the used lane type is given + * but no or limited knowledge about the absolute lane number is available. For example, a cyclist on a cycle-lane or vehicles on a specific lane that is unique for the part of the road (e.g. a bus lane). + * + * @field detailedlanePosition: a single lane position with additional lane details. + * + * @field lanePositionWithLateralDetails: a single lane position with additional details and the lateral position within the lane. + * + * @field trafficIslandPosition: a position on a traffic island, i.e. between two lanes. + * + * @category: Road Topology information + * @revision: Created in V2.2.1 from the DF GeneralizedLanePosition of V2.1.1. + */ +LanePositionOptions ::= CHOICE { + simplelanePosition LanePosition, + simpleLaneType LaneType, + detailedlanePosition LanePositionAndType, + lanePositionWithLateralDetails LanePositionWithLateralDetails, + trafficIslandPosition TrafficIslandPosition, + ... +} + +/** + * This DF is a third-level DF that represents a lane position and is an extended version of @ref LanePositionAndType that adds the distances to the left and right lane border. + * + * It shall additionally include the following components: + * + * @field distanceToLeftBorder: the distance of the transversal position to the left lane border. The real value shall be rounded to the next lower encoding-value. + * + * @field distanceToRightBorder: the distance of the transversal position to the right lane border. The real value shall be rounded to the next lower encoding-value. + * + * @category: Road Topology information + * @revision: Created in V2.2.1 + */ +LanePositionWithLateralDetails ::= SEQUENCE { + COMPONENTS OF LanePositionAndType, + distanceToLeftBorder StandardLength9b, + distanceToRightBorder StandardLength9b, + ... +} + +/** + * This DF indicates the vehicle acceleration at lateral direction and the confidence value of the lateral acceleration. + * + * It shall include the following components: + * + * @field lateralAccelerationValue: lateral acceleration value at a point in time. + * + * @field lateralAccelerationConfidence: confidence value of the lateral acceleration value. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use @ref AccelerationComponent instead. + * @category Vehicle information + * @revision: Description revised in V2.1.1 + */ +LateralAcceleration ::= SEQUENCE { + lateralAccelerationValue LateralAccelerationValue, + lateralAccelerationConfidence AccelerationConfidence +} + +/** + * This DF indicates the vehicle acceleration at longitudinal direction and the confidence value of the longitudinal acceleration. + * + * It shall include the following components: + * + * @field longitudinalAccelerationValue: longitudinal acceleration value at a point in time. + + * @field longitudinalAccelerationConfidence: confidence value of the longitudinal acceleration value. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use @ref AccelerationComponent instead. + * @category: Vehicle information + * @revision: V1.3.1 + */ +LongitudinalAcceleration ::= SEQUENCE { + longitudinalAccelerationValue LongitudinalAccelerationValue, + longitudinalAccelerationConfidence AccelerationConfidence +} + +/** + * This DF represents the estimated position along the longitudinal extension of a carriageway or lane. + * + * It shall include the following components: + * + * @field longitudinalLanePositionValue: the mean value of the longitudinal position along the carriageway or lane w.r.t. an externally defined start position. + * + * @field longitudinalLanePositionConfidence: The confidence value associated to the value. + * + * @category: Road topology information + * @revision: created in V2.1.1, description revised in V2.2.1 + */ +LongitudinalLanePosition ::= SEQUENCE { + longitudinalLanePositionValue LongitudinalLanePositionValue, + longitudinalLanePositionConfidence LongitudinalLanePositionConfidence +} + +/** + * This DF shall contain a list of a lower triangular positive semi-definite matrices. + * + * @category: Sensing information + * @revision: Created in V2.1.1 +*/ +LowerTriangularPositiveSemidefiniteMatrices::= SEQUENCE SIZE (1..4) OF LowerTriangularPositiveSemidefiniteMatrix + +/** + * This DF represents a lower triangular positive semi-definite matrix. + * + * It shall include the following components: + * + * @field componentsIncludedIntheMatrix: the indication of which components of a @ref PerceivedObject are included in the matrix. + * This component also implicitly indicates the number n of included components which defines the size (n x n) of the full correlation matrix "A". + * + * @field matrix: the list of cells of the lower triangular positive semi-definite matrix ordered by columns and by rows. + * + * The number of columns to be included "k" is equal to the number of included components "n" indicated by componentsIncludedIntheMatrix minus 1: k = n-1. + * These components shall be included in the order or their appearance in componentsIncludedIntheMatrix. + * Each column "i" of the lowerTriangularCorrelationMatrixColumns contains k-(i-1) values. + * + * @category: Sensing information + * @revision: Created in V2.1.1 +*/ +LowerTriangularPositiveSemidefiniteMatrix ::= SEQUENCE{ + componentsIncludedIntheMatrix MatrixIncludedComponents, + matrix LowerTriangularPositiveSemidefiniteMatrixColumns +} + +/** + * This DF represents the columns of a lower triangular positive semi-definite matrix, each column not including the main diagonal cell of the matrix. + * Given a matrix "A" of size n x n, the number of @ref CorrelationColumn to be included in the lower triangular matrix is k=n-1. + * + * @category: Sensing information + * @revision: Created in V2.1.1, extension indicator added in V2.2.1 +*/ +LowerTriangularPositiveSemidefiniteMatrixColumns ::= SEQUENCE SIZE (1..13,...) OF CorrelationColumn + +/** + * This DF provides information about the configuration of a road section in terms of MAPEM lanes or connections using a list of @ref MapemExtractedElementReference. + + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ +MapemConfiguration::= SEQUENCE(SIZE(1..16,...)) OF MapemElementReference + +/** + * This DF provides references to an element described in a MAPEM according to ETSI TS 103 301 [i.15], such as a lane or connection at a specific intersection or road segment. + * + * It shall include the following components: + * + * @field mapReference: the optional reference to a MAPEM that describes the intersection or road segment. It is absent if the MAPEM topology is known from the context. + * + * @field laneIds: the optional list of the identifiers of the lanes to be referenced. + * + * @field connectionIds: the optional list of the identifiers of the connections to be referenced. + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ + +MapemElementReference::= SEQUENCE { + mapReference MapReference OPTIONAL, + laneIds MapemLaneList OPTIONAL, + connectionIds MapemConnectionList OPTIONAL, + ... +} +((WITH COMPONENTS {..., laneIds PRESENT}) | + (WITH COMPONENTS {..., connectionIds PRESENT })) + +/** + * This DF provides references to MAPEM lanes using a list of @ref Identifier1B. + * + * @category: Road topology information + * @revision: Created in 2.2.1 +*/ +MapemLaneList ::= SEQUENCE (SIZE(1..8,...)) OF Identifier1B + +/** + * This DF provides references to MAPEM connections using a list of @ref Identifier1B. + * Note: connections are allowed �maneuvers� (e.g. an ingress / egress relation) on an intersection. + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ +MapemConnectionList ::= SEQUENCE (SIZE(1..8,...)) OF Identifier1B + +/** + * This DF indicates a position on a topology description transmitted in a MAPEM according to ETSI TS 103 301 [15]. + * + * It shall include the following components: + * + * @field mapReference: optionally identifies the MAPEM containing the topology information. + * It is absent if the MAPEM topology is known from the context. + * + * @field laneId: optionally identifies the lane in the road segment or intersection topology on which the position is located. + * + * @field connectionId: optionally identifies the connection inside the conflict area of an intersection, i.e. it identifies a trajectory for travelling through the + * conflict area of an intersection which connects e.g an ingress with an egress lane. + * + * @field longitudinalLanePosition: optionally indicates the longitudinal offset of the map-matched position of the object along the lane or connection measured from the start of the lane/connection, along the lane. + * + * @category: Road topology information + * @revision: Created in V2.1.1, definition of longitudinalLanePosition amended in V2.2.1 + */ +MapPosition ::= SEQUENCE { + mapReference MapReference OPTIONAL, + laneId Identifier1B OPTIONAL, + connectionId Identifier1B OPTIONAL, + longitudinalLanePosition LongitudinalLanePosition OPTIONAL, + ... +} + ((WITH COMPONENTS {..., laneId PRESENT, connectionId ABSENT }) | + (WITH COMPONENTS {..., laneId ABSENT, connectionId PRESENT })) + +/** + * This DF provides the reference to the information contained in a MAPEM according to ETSI TS 103 301 [15]. + * + * The following options are provided: + * + * @field roadsegment: option that identifies the description of a road segment contained in a MAPEM. + * + * @field intersection: option that identifies the description of an intersection contained in a MAPEM. + * + * @category: Road topology information + * @revision: Created in V2.1.1 + */ +MapReference::= CHOICE { + roadsegment RoadSegmentReferenceId, + intersection IntersectionReferenceId +} + +/** + * This DF shall contain a list of @ref MapReference. + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ +MapReferences::= SEQUENCE (SIZE(1..8,...)) OF MapReference + + +/** + * This DE indicates a message rate. + * + * @field mantissa: indicates the mantissa. + * + * @field exponent: indicates the exponent. + * + * The specified message rate is: mantissa*(10^exponent) + * + * @unit: Hz + * @category: Communication information + * @revision: Created in V2.1.1 + */ +MessageRateHz::= SEQUENCE { + mantissa INTEGER (1..100), + exponent INTEGER (-5..2) +} + +/** + * This DF provides information about a message with respect to the segmentation process on facility layer at the sender. + * + * It shall include the following components: + * + * @field totalMsgNo: indicates the total number of messages that have been assembled on the transmitter side to encode the information + * during the same messsage generation process. + * + * @field thisMsgNo: indicates the position of the message within of the total set of messages generated during the same message generation process. + * + * @category: Communication information + * @revision: Created in V2.1.1, description revised in V2.2.1 + */ +MessageSegmentationInfo ::= SEQUENCE { + totalMsgNo CardinalNumber3b, + thisMsgNo OrdinalNumber3b +} + +/** + * This DF provides information about the source of and confidence in information. + * + * It shall include the following components: + * + * @field usedDetectionInformation: the type of sensor(s) that is used to provide the detection information. + * + * @field usedStoredInformation: the type of source of the stored information. + * + * @field confidenceValue: an optional confidence value associated to the information. + * + * @category: Basic information + * @revision: Created in V2.2.1 +*/ +MetaInformation::=SEQUENCE{ + usedDetectionInformation SensorTypes, + usedStoredInformation StoredInformationType, + confidenceValue ConfidenceLevel OPTIONAL, + ... +} + +/** + * This DF shall contain a list of @ref MitigationPerTechnologyClass. + * + * @category: Communication information + * @revision: Created in V2.1.1 +*/ +MitigationForTechnologies ::= SEQUENCE (SIZE(1..8)) OF MitigationPerTechnologyClass + +/** + * This DF represents a set of mitigation parameters for a specific technology, as specified in ETSI TS 103 724 [24], clause 7. + * + * It shall include the following components: + * + * @field accessTechnologyClass: channel access technology to which this mitigation is intended to be applied. + * + * @field lowDutyCycle: duty cycle limit. + * @unit: 0,01 % steps + * + * @field powerReduction: the delta value of power to be reduced. + * @unit: dB + * + * @field dmcToffLimit: idle time limit as defined in ETSI TS 103 175 [19]. + * @unit: ms + * + * @field dmcTonLimit: Transmission duration limit, as defined in ETSI EN 302 571 [20]. + * @unit: ms + * + * @note: All parameters are optional, as they may not apply to some of the technologies or + * interference management zone types. Specification details are in ETSI TS 103 724 [24], clause 7. + * + * @category: Communication information + * @revision: Created in V2.1.1 + */ +MitigationPerTechnologyClass ::= SEQUENCE { + accessTechnologyClass AccessTechnologyClass, + lowDutyCycle INTEGER (0 .. 10000) OPTIONAL, + powerReduction INTEGER (0 .. 30) OPTIONAL, + dmcToffLimit INTEGER (0 .. 1200) OPTIONAL, + dmcTonLimit INTEGER (0 .. 20) OPTIONAL, + ... +} + +/** + * This DF indicates both the class and associated subclass that best describes an object. + * + * The following options are available: + * + * @field vehicleSubClass: the object is a road vehicle and the specific subclass is specified. + * + * @field vruSubClass: the object is a VRU and the specific subclass is specified. + * + * @field groupSubClass: the object is a VRU group or cluster and the cluster information is specified. + * + * @field otherSubClass: the object is of a different type than the above and the specific subclass is specified. + * + * @category: Sensing information + * @revision: Created in V2.1.1 + */ +ObjectClass ::= CHOICE { + vehicleSubClass TrafficParticipantType (unknown|passengerCar..tram|agricultural), + vruSubClass VruProfileAndSubprofile, + groupSubClass VruClusterInformation + (WITH COMPONENTS{..., clusterBoundingBoxShape ABSENT}), + otherSubClass OtherSubClass, + ... +} + +/** + * This DF shall contain a list of object classes. + * + * @category: Sensing information + * @revision: Created in V2.1.1 +*/ +ObjectClassDescription ::= SEQUENCE (SIZE(1..8)) OF ObjectClassWithConfidence + +/** + * This DF represents the classification of a detected object together with a confidence level. + * + * It shall include the following components: + * + * @field objectClass: the class of the object. + * + * @field Confidence: the associated confidence level. + * + * @category: Sensing information + * @revision: Created in V2.1.1 +*/ +ObjectClassWithConfidence ::= SEQUENCE { + objectClass ObjectClass, + confidence ConfidenceLevel +} + +/** + * This DF represents a dimension of an object together with a confidence value. + * + * It shall include the following components: + * + * @field value: the object dimension value which can be estimated as the mean of the current distribution. + * + * @field confidence: the associated confidence value. + * + * @category: Sensing information + * @revision: Created in V2.1.1 +*/ +ObjectDimension ::= SEQUENCE { + value ObjectDimensionValue, + confidence ObjectDimensionConfidence +} + +/** + * This DF represents a set of lanes which are partially or fully occupied by an object or event at an externally defined reference position. + * + * @note: In contrast to @ref GeneralizedLanePosition, the dimension of the object or event area (width and length) is taken into account to determine the occupancy, + * i.e. this DF describes the lanes which are blocked by an object or event and not the position of the object / event itself. A confidence is used to describe the + * probability that exactly all the provided lanes are occupied. + * + * It shall include the following components: + * + * @field lanePositionBased: a set of up to `4` lanes that are partially or fully occupied by an object or event, ordered by increasing value of @ref LanePosition. + * Lanes that are partially occupied can be described using the component lanePositionWithLateralDetails of @ref Options, with the following constraints: + * The distance to lane borders which are covered by the object / event shall be set to 0. Only the distances to the leftmost and/or rightmost border which are not covered by + * the object / event shall be provided with values > 0. Those values shall be added to the respective instances of @ref LanePositionOptions, i.e. the first entry shall contain the component distanceToLeftBorder > 0 , + * and/or the last entry shall contain the component distanceToRightBorder > 0; the respective other components of these entries shall be set to 0. + * + * @field mapBased: optional lane information described in the context of a MAPEM as specified in ETSI TS 103 301 [15]. + * If present, it shall describe the same lane(s) as listed in the component lanePositionBased, but using the lane identification of the MAPEM. This component can be used only if a + * MAPEM is available for the reference position (e.g. on an intersection): In this case it is used as a synonym to the mandatory component lanePositionBased. + * + * @field confidence: mandatory confidence information for expressing the probability that all the provided lanes are occupied. It also provides information on how the lane + * information were generated. If none of the sensors were used, the lane information is assumed to be derived directly from the absolute reference position and the related dimension. + * + * @category: Road Topology information + * @revision: Created in V2.2.1 + */ +OccupiedLanesWithConfidence::= SEQUENCE { + lanePositionBased SEQUENCE (SIZE(1..4)) OF LanePositionOptions, + mapBased SEQUENCE (SIZE(1..4)) OF MapPosition OPTIONAL, + confidence MetaInformation, + ... +} + +/** + * This DF indicates the allowed type of occupancy of a parking space/area in terms of time and/or usage. + * + * The following options are available: + * + * @field unknown: indicates that the allowed type of occupancy is unknown. + * + * @field unlimitedOccupancy: indicates that it can be occupied without limits. + * + * @field onlyWhileCharging: indicates that it can be occupied only while charging an electric vehicle. + * + * @field limitedDuration: indicates that it can be occupied for a limited and indicated duration in minutes. + * + * @field onlyWhileChargingLimitedDuration: indicates that it can be occupied only while charging an electric vehicle and only for a limited and indicated duration in minutes. + * + * @field parkingAllowedUntil: indicates that it can be occupied only until an indicated moment in time. + * + * @field forcedParkingUntil: indicates that it can be occupied and departure is possible only after an indicated moment in time. + * + * @category: Road Topology information + * @revision: Created in V2.3.1 +*/ +ParkingOccupancyInfo::= CHOICE { + unknown NULL, + unlimitedOccupancy NULL, + onlyWhileCharging NULL, + limitedDuration INTEGER, + onlyWhileChargingLimitedDuration INTEGER, + parkingAllowedUntil TimestampIts, + forcedParkingUntil TimestampIts, + ... +} + +/** + * This DF provides basic information about the parking capabilities and availabilities of a single parking space. + * + * It shall include the following components: + * + * @field id: the unqiue identifier of the parking space within the parking area. + * + * @field location: the optional location of the geometrical center of the parking space w.r.t. the location of the parking area. + * + * @field status: the actual status of the parking space. + * + * @category: Road Topology information + * @revision: Created in V2.3.1 +*/ +ParkingSpaceBasic ::= SEQUENCE{ + id Identifier2B, + location DeltaReferencePosition OPTIONAL, + status ParkingSpaceStatus +} + +/** + * This DF provides detailed information about the parking capabilities and availabilities of a single parking space. + * + * It is an extension of @ref ParkingSpaceBasic and it shall additionally include the following additional components: + * + * @field arrangementType: the optional arrangement of the parking space w.r.t. other spaces. + * This is component, if present, overrides the common arrangementType defined in the @ref ParkingArea. + * + * @field boundary: the optional physical boundary of the parking space as a polygon w.r.t. the location of the parking space. + * + * @field orientation: the optional orientation of the parking space. + * This is component, if present, overrides the common orientation defined in the @ref ParkingArea. + * + * @field occupancyRule: the occupancy rule applicable to the parking space. + * + * @field chargingStationId: the optional identitfier of a charging station that serves the parking space. + * + * @field accessViaLane: the optional identifier of a lane that provides access to the parking space. + * + * @field accessViaParkingSpaces: the optional identifier(s) of a parking spaces that provide access to the parking space. + * + * @field reservationType: the optional parking reservation type(s) associated to the parking space. + * This is component, if present, overrides the common reservationType defined in the @ref ParkingArea. + * + * @category: Road Topology information + * @revision: Created in V2.3.1 +*/ +ParkingSpaceDetailed ::= SEQUENCE{ + COMPONENTS OF ParkingSpaceBasic, + arrangementType ParkingAreaArrangementType OPTIONAL, + boundary DeltaPositions OPTIONAL, + orientation Wgs84Angle OPTIONAL, + occupancyRule ParkingOccupancyInfo, + chargingStationId Identifier2B OPTIONAL, + accessViaLane Identifier2B OPTIONAL, + accessViaParkingSpaces SEQUENCE (SIZE(0..7)) OF Identifier2B OPTIONAL, + reservationType SEQUENCE (SIZE(1..4,...)) OF ParkingReservationType OPTIONAL, + ... +} + +/** + * This DF indicates the status of parking space. + * + * The following options are available: + * + * @field unknown: indicates that the status is unknown. + * + * @field free: indicates that the parking space is free and hence available to be used. + * + * @field freeUntil: indicates that the parking space is free to be used until an indicated moment in time. + * + * @field fullyOccupied: indicates that the parking space is interely occupied. + * + * @field partiallyOccupied: indicates that the parking space that allows parking of multiple vehicles is occupied by an indicated percentage. + * + * @field occupiedUntil: indicates that the parking space is entirely occupied until an indicated moment in time. + * + * @field reservedUntil: indicates that the parking space is reserved (but not necessarily occupied) until an indicated moment in time. + * + * @field accessBlocked: indicates that the parking space cannot accessed, e.g. due to obstructing vehicles. + * + * @field retrictedUsage: indicates that the parking space is available but that it is not an official parking space and that there are some phyiscal restrictions applicable, + * such as parking behind or in front of other vehicles that, depending on the situation, may then have problems entering or leaving their respective parking spaces. + * + * @category: Road Topology information + * @revision: Created in V2.3.1 +*/ +ParkingSpaceStatus::= CHOICE { + unknown NULL, + free NULL, + freeUntil TimestampIts, + fullyOccupied NULL, + partiallyOccupied INTEGER(0..100), + occupiedUntil TimestampIts, + reservedUntil TimestampIts, + accessBlocked NULL, + retrictedUsage NULL, + ... +} + +/** + * This DF represents a path with a set of path points. + * It shall contain up to `40` @ref PathPoint. + * + * The first PathPoint presents an offset delta position with regards to an external reference position. + * Each other PathPoint presents an offset delta position and optionally an offset travel time with regards to the previous PathPoint. + * + * @category: GeoReference information, Vehicle information + * @revision: created in V2.1.1 based on PathHistory + */ +Path::= SEQUENCE (SIZE(0..40)) OF PathPoint + +/** + * This DF represents estimated/predicted travel time between a position and a predefined reference position. + * + * the following options are available: + * + * @field deltaTimeHighPrecision: delta time with precision of 0,1 s. + * + * @field deltaTimeBigRange: delta time with precision of 10 s. + * + * @field deltaTimeMidRange: delta time with precision of 1 s. + * + * @category: Basic information + * @revision: Created in V2.2.1, added deltaTimeMidRange extension in V2.3.1 + */ +PathDeltaTimeChoice::= CHOICE { + deltaTimeHighPrecision DeltaTimeTenthOfSecond, + deltaTimeBigRange DeltaTimeTenSeconds, + ..., + deltaTimeMidRange DeltaTimeSecond +} + +/** + * This DF represents a path towards a specific point specified in the @ref EventZone. + * + * It shall include the following components: + * + * @field pointOfEventZone: the ordinal number of the point within the DF EventZone, i.e. within the list of EventPoints. + * + * @field path: the associated path towards the point specified in pointOfEventZone. + * The first PathPoint presents an offset delta position with regards to the position of that pointOfEventZone. + * + * @category: GeoReference information + * @revision: Created in V2.2.1 +*/ +PathExtended::= SEQUENCE { + pointOfEventZone INTEGER(1..23), + path Path +} + +/** + * This DF represents a path history with a set of path points. + * It shall contain up to `40` @ref PathPoint. + * + * The first PathPoint presents an offset delta position with regards to an external reference position. + * Each other PathPoint presents an offset delta position and optionally an offset travel time with regards to the previous PathPoint. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use @ref Path instead. + * @category: GeoReference information, Vehicle information + * @revision: semantics updated in V2.1.1, size corrected to 0..40 in V2.2.1 + */ +PathHistory::= SEQUENCE (SIZE(0..40)) OF PathPoint + +/** + * This DF represents a predicted path or trajectory with a set of predicted points and optional information to generate a shape which is estimated to contain the real path. + * It shall contain up to `16` @ref PathPointPredicted. + * + * The first PathPoint presents an offset delta position with regards to an external reference position. + * Each other PathPoint presents an offset delta position and optionally an offset travel time with regards to the previous PathPoint. + * + * @category: GeoReference information + * @revision: created in V2.1.1 , size constraint changed to SIZE(1..16, ...) in V2.2.1, size extended in V2.3.1 + */ +PathPredicted::= SEQUENCE (SIZE(1..16,..., 17..40)) OF PathPointPredicted + +/** + * This DF represents a predicted path, predicted trajectory or predicted path zone together with usage information and a prediction confidence. + * + * It shall include the following components: + * + * @field pathPredicted: the predicted path (pathDeltaTime ABSENT) or trajectory (pathDeltaTime PRESENT) and/or the path zone (symmetricAreaOffset PRESENT). + * + * @field usageIndication: an indication of how the predicted path will be used. + * + * @field confidenceLevel: the confidence that the path/trajectory in pathPredicted will occur as predicted. + * + * @category: GeoReference information + * @revision: created in V2.2.1 + */ +PathPredicted2::= SEQUENCE{ + pathPredicted PathPredicted + ((WITH COMPONENT (WITH COMPONENTS {..., pathDeltaTime ABSENT, symmetricAreaOffset ABSENT})) | + (WITH COMPONENT (WITH COMPONENTS {..., pathDeltaTime PRESENT, symmetricAreaOffset ABSENT})) | + (WITH COMPONENT (WITH COMPONENTS {..., pathDeltaTime ABSENT, symmetricAreaOffset PRESENT})) | + (WITH COMPONENT (WITH COMPONENTS {..., pathDeltaTime PRESENT, symmetricAreaOffset PRESENT}))), + usageIndication UsageIndication, + confidenceLevel ConfidenceLevel, + ... +} + +/** + * This DF represents one or more predicted paths, or trajectories or path zones (zones that include all possible paths/trajectories within its boundaries) using @ref PathPredicted2. + * It shall contain up to `16` @ref PathPredicted2. + * + * @category: GeoReference information + * @revision: V2.2.1 + */ +PathPredictedList ::= SEQUENCE SIZE(1..16,...) OF PathPredicted2 + +/** + * This DF defines an offset waypoint position within a path. + * + * It shall include the following components: + * + * @field pathPosition: The waypoint position defined as an offset position with regards to a pre-defined reference position. + * + * @field pathDeltaTime: The optional travel time separated from a waypoint to the predefined reference position. + * + * @category GeoReference information + * @revision: semantics updated in V2.1.1 + */ +PathPoint ::= SEQUENCE { + pathPosition DeltaReferencePosition, + pathDeltaTime PathDeltaTime OPTIONAL +} + +/** + * This DF defines a predicted offset position that can be used within a predicted path or trajectory, together with optional data to describe a path zone shape. + * + * It shall include the following components: + * + * @field deltaLatitude: the offset latitude with regards to a pre-defined reference position. + * + * @field deltaLongitude: the offset longitude with regards to a pre-defined reference position. + * + * @field horizontalPositionConfidence: the optional confidence value associated to the horizontal geographical position. + * + * @field deltaAltitude: the optional offset altitude with regards to a pre-defined reference position, with default value unavailable. + * + * @field altitudeConfidence: the optional confidence value associated to the altitude value of the geographical position, with default value unavailable. + * + * @field pathDeltaTime: the optional travel time to the waypoint from the predefined reference position. + + * @field symmetricAreaOffset: the optional symmetric offset to generate a shape, see Annex D for details. + * + * @field asymmetricAreaOffset: the optional asymmetric offset to generate a shape, see Annex D for details. + * + * @category GeoReference information + * @revision: Created in V2.1.1, type of pathDeltaTime changed and optionality added, fields symmetricAreaOffset and asymmetricAreaOffset added in V2.2.1 + */ +PathPointPredicted::= SEQUENCE { + deltaLatitude DeltaLatitude, + deltaLongitude DeltaLongitude, + horizontalPositionConfidence PosConfidenceEllipse OPTIONAL, + deltaAltitude DeltaAltitude DEFAULT unavailable, + altitudeConfidence AltitudeConfidence DEFAULT unavailable, + pathDeltaTime PathDeltaTimeChoice OPTIONAL, + symmetricAreaOffset StandardLength9b OPTIONAL, + asymmetricAreaOffset StandardLength9b OPTIONAL, + ... +} + ((WITH COMPONENTS {..., symmetricAreaOffset ABSENT, asymmetricAreaOffset ABSENT}) | + (WITH COMPONENTS {..., symmetricAreaOffset PRESENT, asymmetricAreaOffset ABSENT}) | + (WITH COMPONENTS {..., symmetricAreaOffset PRESENT, asymmetricAreaOffset PRESENT})) + +/** + * This DF represents a list of references to the components of a @ref Traces or @ref TracesExtended DF using the @ref PathId. + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ +PathReferences ::= SEQUENCE (SIZE(1..14)) OF PathId + +/** + * This DE contains information about the status of a vehicle pedal. + * + * It shall include the following components: + * + * @field pedalPositionValue: information about the pedal position. + * + * @category: vehicle information + * @revision: created in V2.3.1 + */ +PedalStatus::= SEQUENCE { + pedalPositionValue PedalPositionValue, + ... +} + +/** + * This DF contains information about a perceived object including its kinematic state and attitude vector in a pre-defined coordinate system and with respect to a reference time. + * + * It shall include the following components: + * + * @field objectId: optional identifier assigned to a detected object. + * + * @field measurementDeltaTime: the time difference from a reference time to the time of the measurement of the object. + * Negative values indicate that the provided object state refers to a point in time before the reference time. + * + * @field position: the position of the geometric centre of the object's bounding box within the pre-defined coordinate system. + * + * @field velocity: the velocity vector of the object within the pre-defined coordinate system. + * + * @field acceleration: the acceleration vector of the object within the pre-defined coordinate system. + * + * @field angles: optional Euler angles of the object bounding box at the time of measurement. + * + * @field zAngularVelocity: optional angular velocity of the object around the z-axis at the time of measurement. + * The angular velocity is measured with positive values considering the object orientation turning around the z-axis using the right-hand rule. + * + * @field lowerTriangularCorrelationMatrices: optional set of lower triangular correlation matrices for selected components of the provided kinematic state and attitude vector. + * + * @field objectDimensionZ: optional z-dimension of object bounding box. + * This dimension shall be measured along the direction of the z-axis after all the rotations have been applied. + * + * @field objectDimensionY: optional y-dimension of the object bounding box. + * This dimension shall be measured along the direction of the y-axis after all the rotations have been applied. + * + * @field objectDimensionX: optional x-dimension of object bounding box. + * This dimension shall be measured along the direction of the x-axis after all the rotations have been applied. + * + * @field objectAge: optional age of the detected and described object, i.e. the difference in time between the moment + * it has been first detected and the reference time of the message. Value `1500` indicates that the object has been observed for more than 1.5s. + * + * @field objectPerceptionQuality: optional confidence associated to the object. + * + * @field sensorIdList: optional list of sensor-IDs which provided the measurement data. + * + * @field classification: optional classification of the described object + * + * @field matchedPosition: optional map-matched position of an object. + * + * @category Sensing information + * @revision: created in V2.1.1 + */ +PerceivedObject ::= SEQUENCE { + objectId Identifier2B OPTIONAL, + measurementDeltaTime DeltaTimeMilliSecondSigned, + position CartesianPosition3dWithConfidence, + velocity Velocity3dWithConfidence OPTIONAL, + acceleration Acceleration3dWithConfidence OPTIONAL, + angles EulerAnglesWithConfidence OPTIONAL, + zAngularVelocity CartesianAngularVelocityComponent OPTIONAL, + lowerTriangularCorrelationMatrices LowerTriangularPositiveSemidefiniteMatrices OPTIONAL, + objectDimensionZ ObjectDimension OPTIONAL, + objectDimensionY ObjectDimension OPTIONAL, + objectDimensionX ObjectDimension OPTIONAL, + objectAge DeltaTimeMilliSecondSigned (0..2047) OPTIONAL, + objectPerceptionQuality ObjectPerceptionQuality OPTIONAL, + sensorIdList SequenceOfIdentifier1B OPTIONAL, + classification ObjectClassDescription OPTIONAL, + mapPosition MapPosition OPTIONAL, + ... +} + +/** +* The data frame PolygonalLine shall contain the definition of a polygonal line (also known as polygonal chain) w.r.t. an externally defined reference position. +* +* The following options are available: +* +* @field deltaPositions: an ordered sequence of delta geographical positions with respect to the previous position, with latitude and longitude, +* with the first instance referring to the reference position and with the order implicitly defining a direction associated with the polygonal line. +* +* @field deltaPositionsWithAltitude: an ordered sequence of delta geographical positions with respect to the previous position, with latitude, longitude and altitude, +* with the first instance referring to the reference position and with the order implicitly defining a direction associated with the polygonal line. +* +* @field absolutePositions: a sequence of absolute geographical positions, with latitude and longitude. +* +* @field absolutePositionsWithAltitude: a sequence of absolute geographical positions, with latitude, longitude and altitude. +* +* @category: GeoReference information +* @revision: created in V2.3.1 based on ISO TS 19321 +*/ +PolygonalLine ::= CHOICE { + deltaPositions DeltaPositions, + deltaPositionsWithAltitude DeltaReferencePositions, + absolutePositions GeoPositionsWoAltitude, + absolutePositionsWithAltitude GeoPositionsWAltitude, + + ... +} + +/** + * This DF represents the shape of a polygonal area or of a right prism. + * + * It shall include the following components: + * + * @field shapeReferencePoint: the optional reference point used for the definition of the shape, relative to an externally specified reference position. + * If this component is absent, the externally specified reference position represents the shape's reference point. + * + * @field polygon: the polygonal area represented by a list of minimum `3` to maximum `16` @ref CartesianPosition3d. + * All nodes of the polygon shall be considered relative to the shape's reference point. + * + * @field height: the optional height, present if the shape is a right prism extending in the positive z-axis. + * + * @category GeoReference information + * @revision: created in V2.1.1 + * + */ +PolygonalShape ::= SEQUENCE { + shapeReferencePoint CartesianPosition3d OPTIONAL, + polygon SequenceOfCartesianPosition3d (SIZE(3..16,...)), + height StandardLength12b OPTIONAL +} + +/** + * This DF indicates the horizontal position confidence ellipse which represents the estimated accuracy with a + * confidence level of 95 %. The centre of the ellipse shape corresponds to the reference + * position point for which the position accuracy is evaluated. + * + * It shall include the following components: + * + * @field semiMajorConfidence: half of length of the major axis, i.e. distance between the centre point + * and major axis point of the position accuracy ellipse. + * + * @field semiMinorConfidence: half of length of the minor axis, i.e. distance between the centre point + * and minor axis point of the position accuracy ellipse. + * + * @field semiMajorOrientation: orientation direction of the ellipse major axis of the position accuracy + * ellipse with regards to the WGS84 north. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * + * + * @category GeoReference information + * @revision: V1.3.1 + */ +PosConfidenceEllipse ::= SEQUENCE { + semiMajorConfidence SemiAxisLength, + semiMinorConfidence SemiAxisLength, + semiMajorOrientation HeadingValue +} + +/** + * This DF indicates the horizontal position confidence ellipse which represents the estimated accuracy with a + * confidence level of 95 %. The centre of the ellipse shape corresponds to the reference + * position point for which the position accuracy is evaluated. + * + * It shall include the following components: + * + * @field semiMajorAxisLength: half of length of the major axis, i.e. distance between the centre point + * and major axis point of the position accuracy ellipse. + * + * @field semiMinorAxisLength: half of length of the minor axis, i.e. distance between the centre point + * and minor axis point of the position accuracy ellipse. + * + * @field semiMajorAxisOrientation: orientation direction of the ellipse major axis of the position accuracy + * ellipse with regards to the WGS84 north. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * + * @category GeoReference information + * @revision: created in V2.1.1 based on @ref PosConfidenceEllipse + */ +PositionConfidenceEllipse ::= SEQUENCE { + semiMajorAxisLength SemiAxisLength, + semiMinorAxisLength SemiAxisLength, + semiMajorAxisOrientation Wgs84AngleValue +} + +/** + * This DF shall contain a list of distances @ref PosPillar that refer to the perpendicular distance between centre of vehicle front bumper + * and vehicle pillar A, between neighbour pillars until the last pillar of the vehicle. + * + * Vehicle pillars refer to the vertical or near vertical support of vehicle, + * designated respectively as the A, B, C or D and other pillars moving in side profile view from the front to rear. + * + * The first value of the DF refers to the perpendicular distance from the centre of vehicle front bumper to + * vehicle A pillar. The second value refers to the perpendicular distance from the centre position of A pillar + * to the B pillar of vehicle and so on until the last pillar. + * + * @category: Vehicle information + * @revision: V1.3.1 + */ +PositionOfPillars ::= SEQUENCE (SIZE(1..3, ...)) OF PosPillar + +/** + * This DF describes a zone of protection inside which the ITS communication should be restricted. + * + * It shall include the following components: + * + * @field protectedZoneType: type of the protected zone. + * + * @field expiryTime: optional time at which the validity of the protected communication zone will expire. + * + * @field protectedZoneLatitude: latitude of the centre point of the protected communication zone. + * + * @field protectedZoneLongitude: longitude of the centre point of the protected communication zone. + * + * @field protectedZoneRadius: optional radius of the protected communication zone in metres. + * + * @field protectedZoneId: the optional ID of the protected communication zone. + * + * @note: A protected communication zone may be defined around a CEN DSRC road side equipment. + * + * @category: Infrastructure information, Communication information + * @revision: revised in V2.1.1 (changed protectedZoneID to protectedZoneId) + */ +ProtectedCommunicationZone ::= SEQUENCE { + protectedZoneType ProtectedZoneType, + expiryTime TimestampIts OPTIONAL, + protectedZoneLatitude Latitude, + protectedZoneLongitude Longitude, + protectedZoneRadius ProtectedZoneRadius OPTIONAL, + protectedZoneId ProtectedZoneId OPTIONAL, + ... +} + +/** + * This DF shall contain a list of @ref ProtectedCommunicationZone provided by a road side ITS-S (Road Side Unit RSU). + * + * It may provide up to 16 protected communication zones information. + * + * @category: Infrastructure information, Communication information + * @revision: V1.3.1 + */ +ProtectedCommunicationZonesRSU ::= SEQUENCE (SIZE(1..16)) OF ProtectedCommunicationZone + +/** + * This DF identifies an organization. + * + * It shall include the following components: + * + * @field countryCode: represents the country code that identifies the country of the national registration administrator for issuers according to ISO 14816. + * + * @field providerIdentifier: identifies the organization according to the national ISO 14816 register for issuers. + * + * @note: See https://www.itsstandards.eu/registries/register-of-nra-i-cs1/ for a list of national registration administrators and their respective registers + * + * @category: Communication information + * @revision: Created in V2.2.1 based on ISO 17573-3 [24] + */ +Provider ::= SEQUENCE { + countryCode CountryCode, + providerIdentifier IssuerIdentifier +} + +/** + * This DF represents activation data for real-time systems designed for operations control, traffic light priorities, track switches, barriers, etc. + * using a range of activation devices equipped in public transport vehicles. + * + * The activation of the corresponding equipment is triggered by the approach or passage of a public transport + * vehicle at a certain point (e.g. a beacon). + * + * @field ptActivationType: type of activation. + * + * @field ptActicationData: data of activation. + * + * Today there are different payload variants defined for public transport activation-data. The R09.x is one of + * the industry standard used by public transport vehicles (e.g. buses, trams) in Europe (e.g. Germany Austria) + * for controlling traffic lights, barriers, bollards, etc. This DF shall include information like route, course, + * destination, priority, etc. + * + * The R09.x content is defined in VDV recommendation 420 [7]. It includes following information: + * - Priority Request Information (pre-request, request, ready to start) + * - End of Prioritization procedure + * - Priority request direction + * - Public Transport line number + * - Priority of public transport + * - Route line identifier of the public transport + * - Route number identification + * - Destination of public transport vehicle + * + * Other countries may use different message sets defined by the local administration. + * @category: Vehicle information + * @revision: V1.3.1 + */ +PtActivation ::= SEQUENCE { + ptActivationType PtActivationType, + ptActivationData PtActivationData +} + +/** + * This DF describes a radial shape. The circular or spherical sector is constructed by sweeping + * the provided range about the reference position specified outside of the context of this DF or + * about the optional shapeReferencePoint. The range is swept between a horizontal start and a + * horizontal end angle in the X-Y plane of a cartesian coordinate system specified outside of the + * context of this DF, in a right-hand positive angular direction w.r.t. the x-axis. + * A vertical opening angle in the X-Z plane may optionally be provided in a right-hand positive + * angular direction w.r.t. the x-axis. + * + * It shall include the following components: + * + * @field shapeReferencePoint: the optional reference point used for the definition of the shape, + * relative to an externally specified reference position. If this component is absent, the + * externally specified reference position represents the shape's reference point. + * + * @field range: the radial range of the shape from the shape's reference point. + * + * @field horizontalOpeningAngleStart: the start of the shape's horizontal opening angle. + * + * @field horizontalOpeningAngleEnd: the end of the shape's horizontal opening angle. + * + * @field verticalOpeningAngleStart: optional start of the shape's vertical opening angle. + * + * @field verticalOpeningAngleEnd: optional end of the shape's vertical opening angle. + * + * @category GeoReference information + * @revision: created in V2.1.1, names and types of the horizontal opening angles changed, constraint added and description revised in V2.2.1 +*/ +RadialShape ::= SEQUENCE { + shapeReferencePoint CartesianPosition3d OPTIONAL, + range StandardLength12b, + horizontalOpeningAngleStart CartesianAngleValue, + horizontalOpeningAngleEnd CartesianAngleValue, + verticalOpeningAngleStart CartesianAngleValue OPTIONAL, + verticalOpeningAngleEnd CartesianAngleValue OPTIONAL +} + ((WITH COMPONENTS {..., verticalOpeningAngleStart ABSENT, verticalOpeningAngleEnd ABSENT }) | + (WITH COMPONENTS {..., verticalOpeningAngleStart PRESENT, verticalOpeningAngleEnd PRESENT })) + + +/** + * This DF describes a list of radial shapes positioned w.r.t. to an offset position defined + * relative to a reference position specified outside of the context of this DF and oriented w.r.t. + * a cartesian coordinate system specified outside of the context of this DF. + * + * It shall include the following components: + * + * @field refPointId: the identification of the reference point in case of a sensor mounted to trailer. Defaults to ITS ReferencePoint (0). + * + * @field xCoordinate: the x-coordinate of the offset position. + * + * @field yCoordinate: the y-coordinate of the offset position. + * + * @field zCoordinate: the optional z-coordinate of the offset position. + * + * @field radialShapesList: the list of radial shape details. + * + * @category: Georeference information + * @revision: created in V2.1.1, description revised in V2.2.1 + */ +RadialShapes ::= SEQUENCE { + refPointId Identifier1B, + xCoordinate CartesianCoordinateSmall, + yCoordinate CartesianCoordinateSmall, + zCoordinate CartesianCoordinateSmall OPTIONAL, + radialShapesList RadialShapesList +} + +/** + * The DF contains a list of @ref RadialShapeDetails. + * + * @category: Georeference information + * @revision: created in V2.1.1 + */ + +RadialShapesList ::= SEQUENCE SIZE(1..16,...) OF RadialShapeDetails + +/** + * This DF describes radial shape details. The circular sector or cone is + * constructed by sweeping the provided range about the position specified outside of the + * context of this DF. The range is swept between a horizontal start and a horizontal end angle in + * the X-Y plane of a right-hand cartesian coordinate system specified outside of the context of + * this DF, in positive angular direction w.r.t. the x-axis. A vertical opening angle in the X-Z + * plane may optionally be provided in positive angular direction w.r.t. the x-axis. + * + * It shall include the following components: + * + * @field range: the radial range of the sensor from the reference point or sensor point offset. + * + * @field horizontalOpeningAngleStart: the start of the shape's horizontal opening angle. + * + * @field horizontalOpeningAngleEnd: the end of the shape's horizontal opening angle. + * + * @field verticalOpeningAngleStart: optional start of the shape's vertical opening angle. + * + * @field verticalOpeningAngleEnd: optional end of the shape's vertical opening angle. + * + * @category: Georeference information + * @revision: created in V2.1.1, description revised and constraint added in V2.2.1 + */ +RadialShapeDetails ::= SEQUENCE { + range StandardLength12b, + horizontalOpeningAngleStart CartesianAngleValue, + horizontalOpeningAngleEnd CartesianAngleValue, + verticalOpeningAngleStart CartesianAngleValue OPTIONAL, + verticalOpeningAngleEnd CartesianAngleValue OPTIONAL +} + ((WITH COMPONENTS {..., verticalOpeningAngleStart ABSENT, verticalOpeningAngleEnd ABSENT }) | + (WITH COMPONENTS {..., verticalOpeningAngleStart PRESENT, verticalOpeningAngleEnd PRESENT })) + +/** + * This DF represents the shape of a rectangular area or a right rectangular prism that is centred + * on a reference position defined outside of the context of this DF and oriented w.r.t. a cartesian + * coordinate system defined outside of the context of this DF. + * + * It shall include the following components: + * + * @field shapeReferencePoint: represents an optional offset point which the rectangle is centred on with + * respect to the reference position. If this component is absent, the externally specified + * reference position represents the shape's reference point. + * + * @field semiLength: represents half the length of the rectangle located in the X-Y Plane. + * + * @field semiBreadth: represents half the breadth of the rectangle located in the X-Y Plane. + * + * @field orientation: represents the optional orientation of the length of the rectangle, + * measured with positive values turning around the Z-axis using the right-hand rule, starting from + * the X-axis. + * + * @field height: represents the optional height, present if the shape is a right rectangular prism + * with height extending in the positive Z-axis. + * + * @category GeoReference information + * @revision: created in V2.1.1, centerPoint renamed to shapeReferencePoint, the type of the field orientation changed and description revised in V2.2.1 + */ +RectangularShape ::= SEQUENCE { + shapeReferencePoint CartesianPosition3d OPTIONAL, + semiLength StandardLength12b, + semiBreadth StandardLength12b, + orientation CartesianAngleValue OPTIONAL, + height StandardLength12b OPTIONAL +} + +/** + * A position within a geographic coordinate system together with a confidence ellipse. + * + * It shall include the following components: + * + * @field latitude: the latitude of the geographical point. + * + * @field longitude: the longitude of the geographical point. + * + * @field positionConfidenceEllipse: the confidence ellipse associated to the geographical position. + * + * @field altitude: the altitude and an altitude accuracy of the geographical point. + * + * @note: this DE is kept for backwards compatibility reasons only. It is recommended to use the @ref ReferencePositionWithConfidence instead. + * @category: GeoReference information + * @revision: description updated in V2.1.1 + */ +ReferencePosition ::= SEQUENCE { + latitude Latitude, + longitude Longitude, + positionConfidenceEllipse PosConfidenceEllipse, + altitude Altitude +} + +/** + * A position within a geographic coordinate system together with a confidence ellipse. + * + * It shall include the following components: + * + * @field latitude: the latitude of the geographical point. + * + * @field longitude: the longitude of the geographical point. + * + * @field positionConfidenceEllipse: the confidence ellipse associated to the geographical position. + * + * @field altitude: the altitude and an altitude accuracy of the geographical point. + * + * @category: GeoReference information + * @revision: created in V2.1.1 based on @ref ReferencePosition but using @ref PositionConfidenceEllipse. + */ +ReferencePositionWithConfidence ::= SEQUENCE { + latitude Latitude, + longitude Longitude, + positionConfidenceEllipse PositionConfidenceEllipse, + altitude Altitude +} + +/** + * This DF shall contain a list of @ref StationType. to which a certain traffic restriction, e.g. the speed limit, applies. + * + * @category: Infrastructure information, Traffic information + * @revision: V1.3.1 + */ +RestrictedTypes ::= SEQUENCE (SIZE(1..3, ...)) OF StationType + +/** + * This DF provides configuration information about a road section. + * + * It shall include the following components: + * + * @field roadSectionDefinition: the topological definition of the road section for which the information in the other components applies throughout its entire length. + * + * @field roadType: the optional type of road on which the section is located. + * + * @field laneConfiguration: the optional configuration of the road section in terms of basic information per lane. + * + * @field mapemConfiguration: the optional configuration of the road section in terms of MAPEM lanes or connections. + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ + +RoadConfigurationSection ::= SEQUENCE { + roadSectionDefinition RoadSectionDefinition, + roadType RoadType OPTIONAL, + laneConfiguration BasicLaneConfiguration OPTIONAL, + mapemConfiguration MapemConfiguration OPTIONAL, + ... +} + ((WITH COMPONENTS {..., laneConfiguration PRESENT}) | + (WITH COMPONENTS {..., mapemConfiguration PRESENT})) + +/** + * This DF shall contain a list of @ref RoadConfigurationSection. + * + * @category: Road Topology information + * @revision: Created in V2.2.1 + */ +RoadConfigurationSectionList::= SEQUENCE (SIZE(1..8,...)) OF RoadConfigurationSection + +/** + * This DF provides the basic topological definition of a road section. + * + * It shall include the following components: + * + * @field startingPointSection: the position of the starting point of the section. + * + * @field lengthOfSection: the optional length of the section along the road profile (i.e. including curves). + * + * @field endingPointSection: the optional position of the ending point of the section. + * If this component is absent, the ending position is implicitly defined by other means, e.g. the starting point of the next RoadConfigurationSection, or the section�s length. + * + * @field connectedPaths: the identifier(s) of the path(s) having one or an ordered subset of waypoints located upstream of the RoadConfigurationSection� starting point. + * + * @field includedPaths: the identifier(s) of the path(s) that covers (either with all its length or with a part of it) a RoadConfigurationSection. + * + * @field isEventZoneIncluded: indicates, if set to TRUE, that the @ref EventZone incl. its reference position covers a RoadConfigurationSection (either with all its length or with a part of it). + * + * @field isEventZoneConnected: indicates, if set to TRUE, that the @ref EventZone incl. its reference position has one or an ordered subset of waypoints located upstream of the RoadConfigurationSection� starting point. + * + * @category: Road topology information + * @revision: Created in V2.2.1 +*/ +RoadSectionDefinition::= SEQUENCE { + startingPointSection GeoPosition, + lengthOfSection StandardLength2B OPTIONAL, + endingPointSection GeoPosition OPTIONAL, + connectedPaths PathReferences, + includedPaths PathReferences, + isEventZoneIncluded BOOLEAN, + isEventZoneConnected BOOLEAN, + ... +} + +/** + * This DF represents a unique id for a road segment + * + * It shall include the following components: + * + * @field region: the optional identifier of the entity that is responsible for the region in which the road segment is placed. + * It is the duty of that entity to guarantee that the @ref Id is unique within the region. + * + * @field id: the identifier of the road segment. + * + * @note: when the component region is present, the RoadSegmentReferenceId is guaranteed to be globally unique. + * @category: GeoReference information + * @revision: created in V2.1.1 + */ +RoadSegmentReferenceId ::= SEQUENCE { + region Identifier2B OPTIONAL, + id Identifier2B +} + +/** + * This DF provides the safe distance indication of a traffic participant with other traffic participant(s). + * + * It shall include the following components: + * + * @field subjectStation: optionally indicates one "other" traffic participant identified by its ITS-S. + * + * @field safeDistanceIndicator: indicates whether the distance between the ego ITS-S and the traffic participant(s) is safe. + * If subjectStation is present then it indicates whether the distance between the ego ITS-S and the traffic participant indicated in the component subjectStation is safe. + * + * @field timeToCollision: optionally indicated the time-to-collision calculated as sqrt(LaDi^2 + LoDi^2 + VDi^2/relative speed + * and represented in the nearest 100 ms. This component may be present only if subjectStation is present. + * + * @note: the abbreviations used are Lateral Distance (LaD), Longitudinal Distance (LoD) and Vertical Distance (VD) + * and their respective thresholds, Minimum Safe Lateral Distance (MSLaD), Minimum Safe Longitudinal Distance (MSLoD), and Minimum Safe Vertical Distance (MSVD). + * + * @category: Traffic information, Kinematic information + * @revision: created in V2.1.1 + */ +SafeDistanceIndication ::= SEQUENCE { + subjectStation StationId OPTIONAL, + safeDistanceIndicator SafeDistanceIndicator, + timeToCollision DeltaTimeTenthOfSecond OPTIONAL, + ... +} + +/** + * This DF shall contain a list of DF @ref CartesianPosition3d. + * + * @category: GeoReference information + * @revision: created in V2.1.1 + */ +SequenceOfCartesianPosition3d ::= SEQUENCE (SIZE(1..16, ...)) OF CartesianPosition3d + +/** + * The DF contains a list of DE @ref Identifier1B. + * + * @category: Basic information + * @revision: created in V2.1.1 +*/ +SequenceOfIdentifier1B ::= SEQUENCE SIZE(1..128, ...) OF Identifier1B + +/** + * The DF contains a list of DF @ref SafeDistanceIndication. + * + * @category: Traffic information, Kinematic information + * @revision: created in V2.1.1 +*/ +SequenceOfSafeDistanceIndication ::= SEQUENCE(SIZE(1..8,...)) OF SafeDistanceIndication + +/** + * The DF shall contain a list of DF @ref TrajectoryInterceptionIndication. + * + * @category: Traffic information, Kinematic information + * @revision: created in V2.1.1 +*/ +SequenceOfTrajectoryInterceptionIndication ::= SEQUENCE (SIZE(1..8,...)) OF TrajectoryInterceptionIndication + +/** + * This DF provides the definition of a geographical area or volume, based on different options. + * + * It is a choice of the following components: + * + * @field rectangular: definition of an rectangular area or a right rectangular prism (with a rectangular base) also called a cuboid, or informally a rectangular box. + * + * @field circular: definition of an area of circular shape or a right circular cylinder. + * + * @field polygonal: definition of an area of polygonal shape or a right prism. + * + * @field elliptical: definition of an area of elliptical shape or a right elliptical cylinder. + * + * @field radial: definition of a radial shape. + * + * @field radialList: definition of list of radial shapes. + * + * @category: GeoReference information + * @revision: Created in V2.1.1 + */ +Shape::= CHOICE { + rectangular RectangularShape, + circular CircularShape, + polygonal PolygonalShape, + elliptical EllipticalShape, + radial RadialShape, + radialShapes RadialShapes, + ... +} + +/** + * This DF represents the speed and associated confidence value. + * + * It shall include the following components: + * + * @field speedValue: the speed value. + * + * @field speedConfidence: the confidence value of the speed value. + * + * @category: Kinematic information + * @revision: V1.3.1 + */ +Speed ::= SEQUENCE { + speedValue SpeedValue, + speedConfidence SpeedConfidence +} + +/** + * This DF provides the indication of change in stability. + * + * It shall include the following components: + * + * @field lossProbability: the probability of stability loss. + * + * @field actionDeltaTime: the period over which the the probability of stability loss is estimated. + * + * @category: Kinematic information + * @revision: V2.1.1 + */ +StabilityChangeIndication ::= SEQUENCE { + lossProbability StabilityLossProbability, + actionDeltaTime DeltaTimeTenthOfSecond, + ... +} + +/** + * This DF represents the steering wheel angle of the vehicle at certain point in time. + * + * It shall include the following components: + * + * @field steeringWheelAngleValue: steering wheel angle value. + * + * @field steeringWheelAngleConfidence: confidence value of the steering wheel angle value. + * + * @category: Vehicle information + * @revision: Created in V2.1.1 + */ +SteeringWheelAngle ::= SEQUENCE { + steeringWheelAngleValue SteeringWheelAngleValue, + steeringWheelAngleConfidence SteeringWheelAngleConfidence +} + +/** + * This DF represents one or more paths using @ref Path. + * + * @category: GeoReference information + * @revision: Description revised in V2.1.1. Is is now based on Path and not on PathHistory + */ +Traces ::= SEQUENCE SIZE(1..7) OF Path + +/** + * This DF represents one or more paths using @ref PathExtended. + * + * @category: GeoReference information + * @revision: Created in V2.2.1 + */ +TracesExtended ::= SEQUENCE SIZE(1..7) OF PathExtended + +/** + * Ths DF represents the a position on a traffic island between two lanes. + * + * It shall include the following components: + * + * @field oneSide: represents one lane. + * + * @field otherSide: represents the other lane. + * + * @category: Road Topology information + * @revision: Created in V2.1.1 + */ +TrafficIslandPosition ::= SEQUENCE { + oneSide LanePositionAndType, + otherSide LanePositionAndType, + ... +} + +/** + * This DF provides detailed information about an attached trailer. + * + * It shall include the following components: + * + * @field refPointId: identifier of the reference point of the trailer. + * + * @field hitchPointOffset: optional position of the hitch point in negative x-direction (according to ISO 8855) from the + * vehicle Reference Point. + * + * @field frontOverhang: optional length of the trailer overhang in the positive x direction (according to ISO 8855) from the + * trailer Reference Point indicated by the refPointID. The value defaults to 0 in case the trailer + * is not overhanging to the front with respect to the trailer reference point. + * + * @field rearOverhang: optional length of the trailer overhang in the negative x direction (according to ISO 8855) from the + * trailer Reference Point indicated by the refPointID. + * + * @field trailerWidth: optional width of the trailer. + * + * @field hitchAngle: optional Value and confidence value of the angle between the trailer orientation (corresponding to the x + * direction of the ISO 8855 [21] coordinate system centered on the trailer) and the direction of + * the segment having as end points the reference point of the trailer and the reference point of + * the pulling vehicle, which can be another trailer or a vehicle looking on the horizontal plane + * xy, described in the local Cartesian coordinate system of the trailer. The + * angle is measured with negative values considering the trailer orientation turning clockwise + * starting from the segment direction. The angle value accuracy is provided with the + * confidence level of 95 %. + * + * @category: Vehicle information + * @revision: Created in V2.1.1 +*/ +TrailerData ::= SEQUENCE { + refPointId Identifier1B, + hitchPointOffset StandardLength1B, + frontOverhang StandardLength1B OPTIONAL, + rearOverhang StandardLength1B OPTIONAL, + trailerWidth VehicleWidth OPTIONAL, + hitchAngle CartesianAngle, + ... +} + +/** + * This DF provides the trajectory interception indication of ego-VRU ITS-S with another ITS-Ss. + * + * It shall include the following components: + * + * @field subjectStation: indicates the subject station. + * + * @field trajectoryInterceptionProbability: indicates the propbability of the interception of the subject station trajectory + * with the trajectory of the station indicated in the component subjectStation. + * + * @field trajectoryInterceptionConfidence: indicates the confidence of interception of the subject station trajectory + * with the trajectory of the station indicated in the component subjectStation. + * + * @category: Vehicle information + * @revision: Created in V2.1.1 + */ +TrajectoryInterceptionIndication ::= SEQUENCE { + subjectStation StationId OPTIONAL, + trajectoryInterceptionProbability TrajectoryInterceptionProbability, + trajectoryInterceptionConfidence TrajectoryInterceptionConfidence OPTIONAL, + ... +} + +/** + * This DF together with its sub DFs Ext1, Ext2 and the DE Ext3 provides the custom (i.e. not ASN.1 standard) definition of an integer with variable lenght, that can be used for example to encode the ITS-AID. + * + * @category: Basic information + * @revision: Created in V2.1.1 + */ +VarLengthNumber::=CHOICE{ + content [0] INTEGER(0..127), -- one octet length + extension [1] Ext1 + } +Ext1::=CHOICE{ + content [0] INTEGER(128..16511), -- two octets length + extension [1] Ext2 +} +Ext2::=CHOICE{ + content [0] INTEGER(16512..2113663), -- three octets length + extension [1] Ext3 + } +Ext3::= INTEGER(2113664..270549119,...) -- four and more octets length + +/** + * This DF indicates the vehicle acceleration at vertical direction and the associated confidence value. + * + * It shall include the following components: + * + * @field verticalAccelerationValue: vertical acceleration value at a point in time. + * + * @field verticalAccelerationConfidence: confidence value of the vertical acceleration value with a predefined confidence level. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use @ref AccelerationComponent instead. + * @category Vehicle information + * @revision: Description revised in V2.1.1 + */ +VerticalAcceleration ::= SEQUENCE { + verticalAccelerationValue VerticalAccelerationValue, + verticalAccelerationConfidence AccelerationConfidence +} + +/** + * This DF provides information related to the identification of a vehicle. + * + * It shall include the following components: + * + * @field wMInumber: World Manufacturer Identifier (WMI) code. + * + * @field vDS: Vehicle Descriptor Section (VDS). + * + * @category: Vehicle information + * @revision: V1.3.1 + */ +VehicleIdentification ::= SEQUENCE { + wMInumber WMInumber OPTIONAL, + vDS VDS OPTIONAL, + ... +} + +/** + * This DF represents the length of vehicle and accuracy indication information. + * + * It shall include the following components: + * + * @field vehicleLengthValue: length of vehicle. + * + * @field vehicleLengthConfidenceIndication: indication of the length value confidence. + * + * @note: this DF is kept for backwards compatibility reasons only. It is recommended to use @ref VehicleLengthV2 instead. + * @category: Vehicle information + * @revision: V1.3.1 + */ +VehicleLength ::= SEQUENCE { + vehicleLengthValue VehicleLengthValue, + vehicleLengthConfidenceIndication VehicleLengthConfidenceIndication +} + +/** + * This DF represents the length of vehicle and accuracy indication information. + * + * It shall include the following components: + * + * @field vehicleLengthValue: length of vehicle. + * + * @field trailerPresenceInformation: information about the trailer presence. + * + * @category: Vehicle information + * @revision: created in V2.1.1 based on @ref VehicleLength but using @ref TrailerPresenceInformation. + */ +VehicleLengthV2 ::= SEQUENCE { + vehicleLengthValue VehicleLengthValue, + trailerPresenceInformation TrailerPresenceInformation +} + +/** + * This DF provides information about the status of the vehicle´s movement control mechanisms. + * + * It shall include the following components: + * + * @field accelerationPedalStatus: information about the status of the acceleration pedal. + * + * @field brakePedalPostionStatus information about the status of the brake pedal. + * + * @field saeAutomationLevel: optional information about the level of driving automation. + * + * @field automationControl: optional information about the controlling mechanism for lateral, or combined lateral and longitudinal movement. + * + * @field accelerationControl: optional information about the controlling mechanism for longitudinal movement. + * + * @field accelerationControlExtension: optional extended information about the controlling mechanism for longitudinal movement. + * + * @category: Vehicle information + * @revision: created in V2.3.1 + */ +VehicleMovementControl::= SEQUENCE { + accelerationPedalStatus PedalStatus, + brakePedalStatus PedalStatus, + saeAutomationLevel SaeAutomationLevel OPTIONAL, + automationControl AutomationControl OPTIONAL, + accelerationControl AccelerationControl OPTIONAL, + accelerationControlExtension AccelerationControlExtension OPTIONAL, + ... +} + +/** + * This DF represents a velocity vector with associated confidence value. + * + * The following options are available: + * + * @field polarVelocity: the representation of the velocity vector in a polar or cylindrical coordinate system. + * + * @field cartesianVelocity: the representation of the velocity vector in a cartesian coordinate system. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +Velocity3dWithConfidence::= CHOICE{ + polarVelocity VelocityPolarWithZ, + cartesianVelocity VelocityCartesian +} + +/** + * This DF represents a velocity vector in a cartesian coordinate system. + + * It shall include the following components: + * + * @field xVelocity: the x component of the velocity vector with the associated confidence value. + * + * @field yVelocity: the y component of the velocity vector with the associated confidence value. + * + * @field zVelocity: the optional z component of the velocity vector with the associated confidence value. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +VelocityCartesian::= SEQUENCE { + xVelocity VelocityComponent, + yVelocity VelocityComponent, + zVelocity VelocityComponent OPTIONAL +} + +/** + * This DF represents a component of the velocity vector and the associated confidence value. + * + * It shall include the following components: + * + * @field value: the value of the component. + * + * @field confidence: the confidence value of the value. + * + * @category: Kinematic information + * @revision: V2.1.1 + */ +VelocityComponent ::= SEQUENCE { + value VelocityComponentValue, + confidence SpeedConfidence +} + +/** + * This DF represents a velocity vector in a polar or cylindrical coordinate system. + * + * It shall include the following components: + * + * @field velocityMagnitude: magnitude of the velocity vector on the reference plane, with the associated confidence value. + * + * @field velocityDirection: polar angle of the velocity vector on the reference plane, with the associated confidence value. + * + * @field zVelocity: the optional z component of the velocity vector along the reference axis of the cylindrical coordinate system, with the associated confidence value. + * + * @category: Kinematic information + * @revision: Created in V2.1.1 + */ +VelocityPolarWithZ::= SEQUENCE { + velocityMagnitude Speed, + velocityDirection CartesianAngle, + zVelocity VelocityComponent OPTIONAL +} + +/** + * This DF provides information about a VRU cluster. + * + * It shall include the following components: + * + * @field clusterId: optional identifier of a VRU cluster. + * + * @field clusterBoundingBoxShape: optionally indicates the shape of the cluster bounding box, per default inside an East-North-Up coordinate system + * centered around a reference point defined outside of the context of this DF. + * + * @field clusterCardinalitySize: indicates an estimation of the number of VRUs in the group, e.g. the known members in the cluster + 1 (for the cluster leader) . + * + * @field clusterProfiles: optionally identifies all the VRU profile types that are estimated to be within the cluster. + * if this component is absent it means that the information is unavailable. + * + * @category: VRU information + * @revision: Created in V2.1.1, description revised in V2.2.1 +*/ +VruClusterInformation ::= SEQUENCE { + clusterId Identifier1B OPTIONAL, + clusterBoundingBoxShape Shape (WITH COMPONENTS{..., elliptical ABSENT, radial ABSENT, radialShapes ABSENT}) OPTIONAL, + clusterCardinalitySize CardinalNumber1B, + clusterProfiles VruClusterProfiles OPTIONAL, + ... +} + +/** + * This DF represents the status of the exterior light switches of a VRU. + * This DF is an extension of the vehicular DE @ref ExteriorLights. + * + * It shall include the following components: + * + * @field vehicular: represents the status of the exterior light switches of a road vehicle. + * + * @field vruSpecific: represents the status of the exterior light switches of a VRU. + * + * @category: VRU information + * @revision: created in V2.1.1 + */ +VruExteriorLights ::= SEQUENCE { + vehicular ExteriorLights, + vruSpecific VruSpecificExteriorLights, + ... +} + +/** + * This DF indicates the profile of a VRU including sub-profile information + * It identifies four options corresponding to the four types of VRU profiles specified in ETSI TS 103 300-2 [18]: + * + * @field pedestrian: VRU Profile 1 - Pedestrian. + * + * @field bicyclistAndLightVruVehicle: VRU Profile 2 - Bicyclist. + * + * @field motorcyclist: VRU Profile 3 - Motorcyclist. + * + * @field animal: VRU Profile 4 - Animal. + * + * @category: VRU information + * @revision: Created in V2.1.1 + */ +VruProfileAndSubprofile ::= CHOICE { + pedestrian VruSubProfilePedestrian, + bicyclistAndLightVruVehicle VruSubProfileBicyclist, + motorcyclist VruSubProfileMotorcyclist, + animal VruSubProfileAnimal, + ... +} + +/** + * This DF represents an angular component along with a confidence value in the WGS84 coordinate system. + * The specific WGS84 coordinate system is specified by the corresponding standards applying this DE. + * + * It shall include the following components: + * + * @field value: the angle value, which can be estimated as the mean of the current distribution. + * + * @field confidence: the confidence value associated to the angle value. + * + * @category: GeoReference information + * @revision: Created in V2.1.1 +*/ +Wgs84Angle ::= SEQUENCE { + value Wgs84AngleValue, + confidence Wgs84AngleConfidence +} + + +/** + * This DF represents a yaw rate of vehicle at a point in time. + * + * It shall include the following components: + * + * @field yawRateValue: yaw rate value at a point in time. + * + * @field yawRateConfidence: confidence value associated to the yaw rate value. + * + * @category: Vehicle Information + * @revision: V1.3.1 + */ +YawRate::= SEQUENCE { + yawRateValue YawRateValue, + yawRateConfidence YawRateConfidence +} + +------------------------------------------ +/** + * ## References: + * 1. ETSI TS 103 900: "Intelligent Transport Systems (ITS); Vehicular Communications; Basic Set of Applications; Part 2: Specification of Cooperative Awareness Basic Service; Release 2". + * 2. ETSI TS 103 831: "Intelligent Transport Systems (ITS); Vehicular Communications; Basic Set of Applications; Part 3: Specifications of Decentralized Environmental Notification Basic Service"; Release 2. + * 3. [European Agreement (Applicable as from 1 January 2011): "Concerning the International Carriage of Dangerous Goods by Road"](http://www.unece.org/trans/danger/publi/adr/adr2011/11ContentsE.html). + * 4. [United Nations: "Recommendations on the Transport of Dangerous Goods - Model Regulations", Twelfth revised edition](http://www.unece.org/trans/danger/publi/unrec/12_e.html). + * 5. ETSI TS 101 539-1: "Intelligent Transport Systems (ITS); V2X Applications; Part 1: Road Hazard Signalling (RHS) application requirements specification". + * 6. ISO 3779 (2011-07): "Road vehicles - Vehicle identification number (VIN) Content and structure". + * 7. VDV recommendation 420 (1992): "Technical Requirements for Automatic Vehicle Location / Control Systems - Radio Data Transmission (BON Version) with Supplement 1 and Supplement 2". + * 8. ISO 1176:1990: "Road vehicles - Masses - Vocabulary and codes". + * 9. ETSI TS 103 916 "Intelligent Transport Systems (ITS); Parking Availability Service Specification; Release 2" + * 10. ETSI TS 103 324 "Intelligent Transport System (ITS); Vehicular Communications; Basic Set of Applications; Collective Perception Service; Release 2" + * 11. ETSI TS 103 882 "Intelligent Transport Systems (ITS); Automated Vehicle Marshalling (AVM); Release 2" + * 12. ETSI TS 103 300-3: "Intelligent Transport Systems (ITS); Vulnerable Road Users (VRU) awareness; Part 3: Specification of VRU awareness basic service; Release 2" + * 13. ETSI TS 103 724: "Intelligent Transport Systems (ITS); Facilities layer function; Interference Management Zone Message (IMZM); Release 2" + * 14. ETSI TS 102 792: "Intelligent Transport Systems (ITS); Mitigation techniques to avoid interference between European CEN Dedicated Short Range Communication (CEN DSRC) equipment and Intelligent Transport Systems (ITS) operating in the 5 GHz frequency range". + * 15. ETSI TS 103 301: "Intelligent Transport Systems (ITS); Vehicular Communications; Basic Set of Applications; Facilities layer protocols and communication requirements for infrastructure services; Release 2". + * 16. UNECE/TRANS/WP.29/78/Rev.4: "Consolidated Resolution on the Construction of Vehicles (R.E.3)". + * 17. ETSI EN 302 890-1: "Intelligent Transport Systems (ITS); Facilities layer function; Part 1: Services Announcement (SA) specification". + * 18. ETSI TS 103 300-2 "Intelligent Transport System (ITS); Vulnerable Road Users (VRU) awareness; Part 2: Functional Architecture and Requirements definition; Release 2" + * 19. ETSI TS 103 175: "Intelligent Transport Systems (ITS); Cross Layer DCC Management Entity for operation in the ITS G5A and ITS G5B medium" + * 20. ETSI EN 302 571: "Intelligent Transport Systems (ITS); Radiocommunications equipment operating in the 5 855 MHz to 5 925 MHz frequency band; Harmonised Standard covering the essential requirements of article 3.2 of Directive 2014/53/EU" + * 21. ISO 8855: "Road vehicles - Vehicle dynamics and road-holding ability - Vocabulary". + * 22. ISO 3833: "Road vehicles - Types - Terms and definitions". + * 23. ISO 14816:2015 + Amd1:2019: " Road transport and traffic telematics � Automatic vehicle and equipment identification � Numbering and data structure" + * 24. ISO 17573-3: "Electronic fee collection � System architecture for vehicle-related tolling � Part 3: Data dictionary" + * 25. ISO 3166-1: "Codes for the representation of names of countries and their subdivisions � Part 1: Country code" + * 26. SAE J3016: "Taxonomy and Definitions for Terms Related to Driving Automation Systems for On-Road Motor Vehicles" +*/ + +END + diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/Rocket.asn b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/Rocket.asn new file mode 100644 index 0000000000000000000000000000000000000000..3524725777a7d6e34bb5f5ebfd6f83985496e0d0 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1/Rocket.asn @@ -0,0 +1,17 @@ +---- +World-Schema DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + Rocket ::= SEQUENCE + { + range INTEGER, + name UTF8String (SIZE(1..16)), + message UTF8String DEFAULT "Hello World" , + fuel ENUMERATED {solid, liquid, gas}, + speed CHOICE + { + mph INTEGER, + kmph INTEGER + } OPTIONAL, + payload SEQUENCE OF UTF8String + } +END diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/org/etsi/mts/tdl/asn1/converter/tests/ASN1ConverterInjectorProvider.java b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/org/etsi/mts/tdl/asn1/converter/tests/ASN1ConverterInjectorProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..639760144ce2483adaeb5f295507b05a1a61ed9f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/org/etsi/mts/tdl/asn1/converter/tests/ASN1ConverterInjectorProvider.java @@ -0,0 +1,31 @@ +package org.etsi.mts.tdl.asn1.converter.tests; + +import com.google.inject.Injector; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.xtext.testing.IInjectorProvider; +import org.etsi.mts.tdl.tdlPackage; +import org.etsi.mts.tdl.TDLtxStandaloneSetup; + +public class ASN1ConverterInjectorProvider implements IInjectorProvider { + + protected Injector injector; + + @Override + public Injector getInjector() { + if (injector == null) { + if (!EPackage.Registry.INSTANCE.containsKey(tdlPackage.eNS_URI)) { + EPackage.Registry.INSTANCE.put(tdlPackage.eNS_URI, tdlPackage.eINSTANCE); + } + if (!EPackage.Registry.INSTANCE.containsKey("http://www.etsi.org/spec/TDL/1.3.1/structured")) { + EPackage.Registry.INSTANCE.put("http://www.etsi.org/spec/TDL/1.3.1/structured", + org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage.eINSTANCE); + } + if (!EPackage.Registry.INSTANCE.containsKey("http://www.etsi.org/spec/TDL/1.3.1/configurations")) { + EPackage.Registry.INSTANCE.put("http://www.etsi.org/spec/TDL/1.3.1/configurations", + org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage.eINSTANCE); + } + this.injector = new TDLtxStandaloneSetup().createInjectorAndDoEMFRegistration(); + } + return injector; + } +} diff --git a/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/org/etsi/mts/tdl/asn1/converter/tests/ASN1ConverterParsingTest.java b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/org/etsi/mts/tdl/asn1/converter/tests/ASN1ConverterParsingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2f0d3bec7861b9d7ef123c26cdb4e51a59f45407 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn1.converter.tests/src/org/etsi/mts/tdl/asn1/converter/tests/ASN1ConverterParsingTest.java @@ -0,0 +1,293 @@ +package org.etsi.mts.tdl.asn1.converter.tests; + +import java.io.File; +import java.net.URL; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import org.eclipse.xtext.testing.InjectWith; +import org.eclipse.xtext.testing.extensions.InjectionExtension; +import org.eclipse.xtext.testing.util.ParseHelper; +import org.etsi.mts.tdl.Package; +import org.etsi.mts.tdl.tdlPackage; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.TestFactory; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.google.inject.Inject; + +/** + * Tests that the ASN.1-to-TDL converter produces syntactically valid TDL output. + *

+ * Two modes of operation: + *

    + *
  • Single-file: {@code .asn}/{@code .asn1} files directly in the test folder + * are each converted independently.
  • + *
  • Grouped: Subdirectories in the test folder are passed as a whole to the + * converter, so that cross-module {@code IMPORTS} resolve correctly.
  • + *
+ *

+ * Configuration via system properties: + *

    + *
  • {@code asn1.converter.dir} — path to the converter project (default: resolved relative to working dir)
  • + *
  • {@code python.executable} — Python interpreter command (default: venv in converter dir, else {@code python})
  • + *
  • {@code asn1.test.files} — path to folder with ASN.1 input files (default: {@code src/asn1})
  • + *
  • {@code converter.timeout} — max seconds to wait for the converter process (default: 120)
  • + *
  • {@code asn1.test.output.dir} — if set, converter output is saved to this directory (default: not saved)
  • + *
+ */ +@ExtendWith(InjectionExtension.class) +@InjectWith(ASN1ConverterInjectorProvider.class) +public class ASN1ConverterParsingTest { + + static { + tdlPackage.eINSTANCE.getName(); + org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage.eINSTANCE.getName(); + org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage.eINSTANCE.getName(); + } + + @Inject + private ParseHelper parseHelper; + + @TestFactory + public Collection testConvertedFiles() throws Exception { + List tests = new ArrayList<>(); + File asn1Folder = findASN1Folder(); + + if (asn1Folder == null || !asn1Folder.exists()) { + System.err.println("WARNING: ASN.1 test folder not found. No tests generated."); + return tests; + } + + // Single-file tests: .asn/.asn1 files directly in the folder + File[] files = asn1Folder.listFiles( + (dir, name) -> name.endsWith(".asn") || name.endsWith(".asn1")); + if (files != null) { + Arrays.sort(files); + for (File file : files) { + tests.add(DynamicTest.dynamicTest( + "Convert & Parse: " + file.getName(), + () -> verifyConversion(file.getName(), file))); + } + } + + // Grouped tests: subdirectories containing related schemas + File[] dirs = asn1Folder.listFiles(File::isDirectory); + if (dirs != null) { + Arrays.sort(dirs); + for (File dir : dirs) { + if (containsASN1Files(dir)) { + tests.add(DynamicTest.dynamicTest( + "Convert & Parse group: " + dir.getName(), + () -> verifyConversion(dir.getName(), dir))); + } + } + } + + if (tests.isEmpty()) { + System.err.println("WARNING: No .asn/.asn1 files or groups found in " + asn1Folder); + } + return tests; + } + + private boolean containsASN1Files(File dir) { + File[] files = dir.listFiles( + (d, name) -> name.endsWith(".asn") || name.endsWith(".asn1")); + return files != null && files.length > 0; + } + + /** + * Converts the given ASN.1 input (file or directory) and validates the TDL output. + * + * @param label display name for error messages + * @param input a single {@code .asn} file or a directory of related schemas + */ + private void verifyConversion(String label, File input) throws Exception { + // Step 1: Run the converter + String tdlContent = runConverter(label, input); + Assertions.assertFalse(tdlContent.isBlank(), + "Converter produced empty output for " + label); + + // Step 1b: Optionally save the output + saveOutput(label, tdlContent); + + // Step 2: Parse the TDL output + Package result = parseHelper.parse(tdlContent); + Assertions.assertNotNull(result, + "Parser returned null for converted output of " + label); + + // Step 3: Check for syntax errors + var errors = result.eResource().getErrors(); + if (!errors.isEmpty()) { + StringBuilder sb = new StringBuilder(); + sb.append("Syntax errors in converted output of ").append(label).append(":\n"); + for (var error : errors) { + sb.append(" Line ").append(error.getLine()) + .append(": ").append(error.getMessage()).append("\n"); + } + sb.append("\n--- Generated TDL content ---\n"); + String[] lines = tdlContent.split("\n"); + for (int i = 0; i < lines.length; i++) { + sb.append(String.format("%4d: %s%n", i + 1, lines[i])); + } + Assertions.fail(sb.toString()); + } + } + + /** + * Runs the Python converter on the given ASN.1 input and returns the generated TDL content. + * + * @param label display name for error messages + * @param input a single {@code .asn} file, or a directory (the converter scans it recursively) + */ + private String runConverter(String label, File input) throws Exception { + File converterDir = findConverterDir(); + String python = findPython(converterDir); + int timeout = Integer.parseInt(System.getProperty("converter.timeout", "120")); + + File tempFile = File.createTempFile("asn1_converted_", ".tdl"); + tempFile.deleteOnExit(); + + try { + List command = new ArrayList<>(List.of( + python, "asn1_cli.py", "convert", + "--format", "tdl", + "-o", tempFile.getAbsolutePath())); + + if (input.isDirectory()) { + // Pass the directory — the converter scans it for .asn/.asn1 recursively + command.add(input.getAbsolutePath()); + } else { + command.add(input.getAbsolutePath()); + } + + ProcessBuilder pb = new ProcessBuilder(command); + pb.directory(converterDir); + pb.redirectErrorStream(true); + + Process process = pb.start(); + String processOutput = new String(process.getInputStream().readAllBytes()); + boolean finished = process.waitFor(timeout, TimeUnit.SECONDS); + + if (!finished) { + process.destroyForcibly(); + Assertions.fail("Converter timed out after " + timeout + "s for " + label); + } + + int exitCode = process.exitValue(); + if (exitCode != 0) { + StringBuilder sb = new StringBuilder(); + sb.append("Converter failed (exit code ").append(exitCode) + .append(") for ").append(label).append(":\n") + .append(processOutput); + if (input.isDirectory()) { + sb.append("\nInput files in ").append(input.getName()).append("/:\n"); + File[] asn1Files = input.listFiles( + (d, n) -> n.endsWith(".asn") || n.endsWith(".asn1")); + if (asn1Files != null) { + for (File f : asn1Files) { + sb.append(" ").append(f.getName()).append("\n"); + } + } + } + Assertions.fail(sb.toString()); + } + + return new String(Files.readAllBytes(tempFile.toPath())); + } finally { + tempFile.delete(); + } + } + + private void saveOutput(String label, String tdlContent) throws Exception { + String outputDir = System.getProperty("asn1.test.output.dir"); + if (outputDir == null) return; + + File dir = new File(outputDir); + dir.mkdirs(); + String safeName = label.replaceAll("[^a-zA-Z0-9._-]", "_"); + File outputFile = new File(dir, safeName + ".tdl"); + Files.writeString(outputFile.toPath(), tdlContent); + System.out.println("Saved converter output to " + outputFile.getAbsolutePath()); + } + + private File findConverterDir() { + String dir = System.getProperty("asn1.converter.dir"); + if (dir != null) { + File f = new File(dir); + if (f.exists()) return f; + } + + String userDir = System.getProperty("user.dir"); + + // When running from the test project directory + File f = new File(userDir, "../../../ttf-045"); + if (f.exists()) return f; + + // When running from the ide/ directory + f = new File(userDir, "../../ttf-045"); + if (f.exists()) return f; + + // When running from the TOP/ directory + f = new File(userDir, "ttf-045"); + if (f.exists()) return f; + + throw new RuntimeException( + "Cannot find converter directory (ttf-045). " + + "Set system property -Dasn1.converter.dir= " + + "or run from a recognized working directory. " + + "Current user.dir: " + userDir); + } + + private File findASN1Folder() { + String dir = System.getProperty("asn1.test.files"); + if (dir != null) return new File(dir); + + URL url = getClass().getResource("/asn1"); + if (url != null) { + try { + return new File(url.toURI()); + } catch (Exception e) { /* fall through */ } + } + + String userDir = System.getProperty("user.dir"); + File f = new File(userDir, "src/asn1"); + if (f.exists()) return f; + + f = new File(userDir, + "plugins/org.etsi.mts.tdl.asn1.converter.tests/src/asn1"); + if (f.exists()) return f; + + return null; + } + + /** + * Resolves the Python executable. Priority: + *
    + *
  1. {@code python.executable} system property
  2. + *
  3. Virtual environment inside the converter directory + * ({@code .venv/Scripts/python.exe} on Windows, + * {@code .venv/bin/python} on Unix)
  4. + *
  5. System-wide {@code python}
  6. + *
+ */ + private String findPython(File converterDir) { + String explicit = System.getProperty("python.executable"); + if (explicit != null) return explicit; + + // Check for a venv in the converter directory + File venvWin = new File(converterDir, ".venv/Scripts/python.exe"); + if (venvWin.exists()) return venvWin.getAbsolutePath(); + + File venvUnix = new File(converterDir, ".venv/bin/python"); + if (venvUnix.exists()) return venvUnix.getAbsolutePath(); + + return "python"; + } +} diff --git a/plugins/org.etsi.mts.tdl.asn2tdl/.classpath b/plugins/org.etsi.mts.tdl.asn2tdl/.classpath index 55ba7d0360dd1041daacbd0193fab6d15a204fb8..b6a172e3cfa41f0aaad9acf1a2aa7980a13da71e 100644 --- a/plugins/org.etsi.mts.tdl.asn2tdl/.classpath +++ b/plugins/org.etsi.mts.tdl.asn2tdl/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.asn2tdl/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.asn2tdl/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.asn2tdl/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.asn2tdl/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.asn2tdl/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.asn2tdl/META-INF/MANIFEST.MF index 407d3443e36ffa92436b6874a07d2f9d8cdd6603..50656cc2118b7914d63b20809ab42d8f533052a4 100644 --- a/plugins/org.etsi.mts.tdl.asn2tdl/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.asn2tdl/META-INF/MANIFEST.MF @@ -4,12 +4,12 @@ Bundle-Name: ASN.1 to TDL Generator Bundle-SymbolicName: org.etsi.mts.tdl.asn2tdl Bundle-Version: 1.0.0.qualifier Automatic-Module-Name: org.etsi.mts.tdl.asn2tdl +Bundle-Activator: org.etsi.mts.tdl.asn2tdl.Activator Bundle-Vendor: ETSI Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.emf.ecore, org.etsi.mts.tdl.model, - org.eclipse.ocl.xtext.essentialocl, org.etsi.mts.tdl.common Export-Package: org.etsi.mts.tdl.asn2tdl Bundle-ClassPath: lib/antlr-2.7.7.jar, diff --git a/plugins/org.etsi.mts.tdl.asn2tdl/src/org/etsi/mts/tdl/asn2tdl/ASNConverter.java b/plugins/org.etsi.mts.tdl.asn2tdl/src/org/etsi/mts/tdl/asn2tdl/ASNConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..66611cab7ce93ec2305e11ea7dd8cbadb6b70ffd --- /dev/null +++ b/plugins/org.etsi.mts.tdl.asn2tdl/src/org/etsi/mts/tdl/asn2tdl/ASNConverter.java @@ -0,0 +1,54 @@ +package org.etsi.mts.tdl.asn2tdl; + +import java.io.File; +import java.util.List; + +import org.eclipse.emf.ecore.resource.Resource; +import org.etsi.mts.tdl.resources.ResourceHandler; +import org.etsi.mts.tdl.transform.Converter; + +public class ASNConverter implements Converter { + public String processToString(String inputPath, String outputPath) { + return processToString(inputPath, outputPath, "SOURCE_MAPPING", "TARGET_MAPPING"); + } + + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) { + System.out.println("Exporting: "+outputPath+ " : "+ new File(outputPath).getAbsolutePath()); + ASN2TDLTranslator translator = new ASN2TDLTranslator(); + String content = "Package imported {}"; + try { + Resource tr = ResourceHandler.create(outputPath); + translator.setTargetResource(tr); + translator.initTargetResource(translator.cleanName(new File(inputPath).getName())); + translator.translate(inputPath); + content = ResourceHandler.getText(tr); + } catch (Exception e) { + e.printStackTrace(); + } + return content; + } + + @Override + public String getExtension() { + return "asn"; + } + + @Override + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping, + boolean inline) { + return processToString(inputPath, outputPath, sourceMapping, targetMapping); + } + + @Override + public String processToString(List inputPaths, String outputPath) { + //TODO: integrate + String content = "Package Imported { \n"; + for (String path : inputPaths) { + content += processToString(path, outputPath); + content += "\n"; + } + content +="}"; + return content; +} +} + diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/Activator.java b/plugins/org.etsi.mts.tdl.asn2tdl/src/org/etsi/mts/tdl/asn2tdl/Activator.java similarity index 51% rename from plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/Activator.java rename to plugins/org.etsi.mts.tdl.asn2tdl/src/org/etsi/mts/tdl/asn2tdl/Activator.java index 7a3011b0292e6bed534f8f393ee1087dd54c9857..5cb7cb724cdba48fd398e4c47e2073e73cf5863f 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/Activator.java +++ b/plugins/org.etsi.mts.tdl.asn2tdl/src/org/etsi/mts/tdl/asn2tdl/Activator.java @@ -1,16 +1,20 @@ -package org.etsi.mts.tdl.tools.to.docx.ui; +package org.etsi.mts.tdl.asn2tdl; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.plugin.AbstractUIPlugin; +import java.util.Hashtable; + +import org.etsi.mts.tdl.transform.AbstractTranslator; +import org.etsi.mts.tdl.transform.Converter; +import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; /** * The activator class controls the plug-in life cycle */ -public class Activator extends AbstractUIPlugin { +//public class Activator extends Plugin { +public class Activator implements BundleActivator { // The plug-in ID - public static final String PLUGIN_ID = "org.etsi.mts.tdl.tools.to.docx.ui"; //$NON-NLS-1$ + public static final String PLUGIN_ID = "org.etsi.mts.tdl.asn2tdl"; //$NON-NLS-1$ // The shared instance private static Activator plugin; @@ -26,7 +30,11 @@ public class Activator extends AbstractUIPlugin { * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) */ public void start(BundleContext context) throws Exception { - super.start(context); +// super.start(context); + Hashtable properties = new Hashtable(); + properties.put("type", PLUGIN_ID); + context.registerService(Converter.class.getName(), new ASNConverter(), properties); + context.registerService(AbstractTranslator.class.getName(), new ASN2TDLTranslator(), properties); plugin = this; } @@ -36,7 +44,7 @@ public class Activator extends AbstractUIPlugin { */ public void stop(BundleContext context) throws Exception { plugin = null; - super.stop(context); +// super.stop(context); } /** @@ -48,14 +56,4 @@ public class Activator extends AbstractUIPlugin { return plugin; } - /** - * Returns an image descriptor for the image file at the given - * plug-in relative path - * - * @param path the path - * @return the image descriptor - */ - public static ImageDescriptor getImageDescriptor(String path) { - return imageDescriptorFromPlugin(PLUGIN_ID, path); - } } diff --git a/plugins/org.etsi.mts.tdl.common/.classpath b/plugins/org.etsi.mts.tdl.common/.classpath index 685a6999c9acba0d0158b0929d7a4d384644452e..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.common/.classpath +++ b/plugins/org.etsi.mts.tdl.common/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.common/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.common/.settings/org.eclipse.jdt.core.prefs index a58ebdcad300d0a088dcbd63941d2c89e78a4f98..1e0cb16bbc76c98cc42fff6b95cc023b7eb74830 100644 --- a/plugins/org.etsi.mts.tdl.common/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.common/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -12,4 +12,4 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.common/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.common/META-INF/MANIFEST.MF index fd3a49539fa5085f0a0c69483d2ffded694b893a..958da0904273e54bf7f8c9c230048005e4ebf9ce 100644 --- a/plugins/org.etsi.mts.tdl.common/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.common/META-INF/MANIFEST.MF @@ -1,13 +1,18 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Common +Bundle-Name: TDL Common Components Bundle-SymbolicName: org.etsi.mts.tdl.common Bundle-Version: 1.0.0.qualifier Automatic-Module-Name: org.etsi.mts.tdl.common +Bundle-Activator: org.etsi.mts.tdl.common.Activator Require-Bundle: org.eclipse.xtext, org.etsi.mts.tdl.model, org.eclipse.core.runtime, - org.eclipse.osgi + org.eclipse.osgi, + org.eclipse.core.resources, + org.eclipse.emf.common, + org.eclipse.xtext.xbase, + com.google.gson Export-Package: org.etsi.mts.tdl, org.etsi.mts.tdl.resources, org.etsi.mts.tdl.scoping, diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/TDLValueConverterService.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/TDLValueConverterService.java index d0ec6134de5bc4fe49da576d7513f0f4087b61dd..a7624b7bc4eba89a689447e60813ecb9789e2cd1 100644 --- a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/TDLValueConverterService.java +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/TDLValueConverterService.java @@ -10,6 +10,7 @@ public class TDLValueConverterService extends EString2XtextConverter { private IdentifierValueConverter identifierValueConverter; private QIdentifierValueConverter qidentifierValueConverter; + private GRIdentifierValueConverter gridentifierValueConverter; @ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.Identifier") public IValueConverter Identifier() { @@ -37,7 +38,10 @@ public class TDLValueConverterService extends EString2XtextConverter { @ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.GRIdentifier") public IValueConverter GRIdentifier() { - return this.QIdentifier(); +// return this.QIdentifier(); + if (this.gridentifierValueConverter == null) + this.gridentifierValueConverter = new GRIdentifierValueConverter(this.ID()); + return this.gridentifierValueConverter; } @ValueConverter(rule = "GRIdentifier") @@ -88,4 +92,29 @@ class QIdentifierValueConverter extends IdentifierValueConverter { } return String.join(".", parts); } +} + +class GRIdentifierValueConverter extends IdentifierValueConverter { + + public GRIdentifierValueConverter(IValueConverter iValueConverter) { + super(iValueConverter); + } + + @Override + public String toValue(String string, INode node) throws ValueConverterException { + String[] parts = string.split("::"); + for (int i = 0; i < parts.length; i++) { + parts[i] = super.toValue(parts[i], node); + } + return String.join("::", parts); + } + + @Override + public String toString(String value) throws ValueConverterException { + String[] parts = value.split("::"); + for (int i = 0; i < parts.length; i++) { + parts[i] = super.toString(parts[i]); + } + return String.join("::", parts); + } } \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/common/Activator.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/common/Activator.java new file mode 100644 index 0000000000000000000000000000000000000000..de3cb3be2313b82ad858ddeffa00895753d1c9e7 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/common/Activator.java @@ -0,0 +1,44 @@ +package org.etsi.mts.tdl.common; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.etsi.mts.tdl.common"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/resources/FileFinder.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/resources/FileFinder.java new file mode 100644 index 0000000000000000000000000000000000000000..ff996cb6662b6499fe52a0e5739f9b1e43482ae1 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/resources/FileFinder.java @@ -0,0 +1,25 @@ +package org.etsi.mts.tdl.resources; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.runtime.CoreException; + +public abstract class FileFinder implements IResourceVisitor { + + public IFile file; + + @Override + public boolean visit(IResource resource) throws CoreException { + if (file != null) + return false; + if (resource.getType() != IResource.FILE) + return true; + if (mathces((IFile) resource)) { + this.file = (IFile) resource; + } + return file == null; + } + + abstract protected boolean mathces(IFile file); +} diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/resources/ResourceHandler.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/resources/ResourceHandler.java index 59f0de159fc1f44ad87bde96606caa471d88e1dd..31e7790ba0dd10a082f7c7ac155bd54acd0f344d 100644 --- a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/resources/ResourceHandler.java +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/resources/ResourceHandler.java @@ -1,16 +1,179 @@ package org.etsi.mts.tdl.resources; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceVisitor; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.xtext.GrammarUtil; +import org.eclipse.xtext.IGrammarAccess; +import org.eclipse.xtext.resource.IResourceServiceProvider; +import org.eclipse.xtext.resource.XtextResourceSet; +import org.eclipse.xtext.serializer.impl.Serializer; +import org.etsi.mts.tdl.Package; import org.osgi.framework.Bundle; +import com.google.inject.Injector; + public class ResourceHandler { + public static Injector getTxInjector() { + Injector injector = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(org.eclipse.emf.common.util.URI.createFileURI("t.tdltx")).get(Injector.class); + return injector; + } + + public static Set getTdlGrammarKeywords() { + return getTdlGrammarKeywords(getTxInjector()); + } + public static Set getTdlGrammarKeywords(Injector injector) { + IGrammarAccess grammarAccess = injector.getInstance(IGrammarAccess.class); + if (grammarAccess != null) + return GrammarUtil.getAllKeywords(grammarAccess.getGrammar()); + return Collections.EMPTY_SET; + } + + public static ResourceSet getResourceSet() { + return getResourceSet(getTxInjector()); + } + + public static ResourceSet getResourceSet(Injector injector) { + return injector.getInstance(XtextResourceSet.class); + } + + /** + * Creates a new resource at the specified location. + * @param resourceSet Resource Set. + * @param filename Location of the resource to be loaded. + * @return An empty resource loaded from the file. + * @throws Exception + */ + public static Resource create(ResourceSet resourceSet, String filename) throws Exception { + Resource existing = resourceSet.getResource(org.eclipse.emf.common.util.URI.createFileURI(filename), false); + if (existing != null) { + existing.delete(Collections.emptyMap()); + } + Resource resource = resourceSet.createResource(org.eclipse.emf.common.util.URI.createFileURI(filename)); + return resource; + } + + public static Resource create(String filename) throws Exception { + return create(getResourceSet(), filename); + } + + /** + * Loads an existing resource from a file. + * @param filename location of the resource to be loaded. + * @return A resource loaded from the file. + */ + public static Resource load(String filename) { + Resource resource = getResourceSet().getResource(org.eclipse.emf.common.util.URI.createURI(filename), true); + return resource; + } + + /** + * Link / resolve all loaded resources. + */ + public static void link() { + EcoreUtil.resolveAll(getResourceSet()); + } + + /** + * Check all resources in the shared resourceSet. + */ + public static void check() { + //TODO: check automatically? make optional in case of performance or redundancy concerns? +// TDLHelper.link(); + getResourceSet().getResources().forEach(ResourceHandler::check); + } + + /** + * Check resource in the shared resourceSet. Load if needed. + * @param filename location of the resource to be checked. + */ + public static void check(String filename) { + Resource r = ResourceHandler.load(filename); + check(r); + } + + /** + * Check resource. + * @param r the resource to be checked. + */ + public static void check(Resource r) { + r.getErrors().forEach(e -> System.out.println("Error: "+r.getURI().lastSegment()+": "+e.getLine()+": "+e.getMessage())); + r.getWarnings().forEach(e -> System.out.println("Warning: "+r.getURI().lastSegment()+": "+e.getLine()+": "+e.getMessage())); + } + + + /** + * Store resource contents in a file. + * @param resource A resource to be saved. + * @throws Exception + */ + public static void store(Resource resource, boolean derived) throws Exception { + if (derived) { + IFile file = resourceToFile(resource); + if (file != null) { + if (!file.exists()) + file.create(new ByteArrayInputStream(new byte[0]), false, null); + file.setDerived(derived, new NullProgressMonitor()); + } + } + resource.save(Collections.emptyMap()); + } + + private static IFile resourceToFile(Resource resource) { + org.eclipse.emf.common.util.URI uri = resource.getURI(); + return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true))); + } + + + /** + * Get textual representation of resource contents. + * @param injector Injector. + * @param resource A resource to be represented. + * @throws Exception + */ + public static String getText(Injector injector, Resource resource) throws Exception { +// if (resource instanceof XtextResource) { +// return NodeModelUtils.getNode(resource.getContents().get(0)).getText(); +// } else { + //TODO: this needs to be more robust for the desired format + Serializer serializer = injector.getInstance(Serializer.class); + return serializer.serialize(resource.getContents().get(0)); +// } + } + + public static String getText(Resource resource) throws Exception { + return getText(getTxInjector(), resource); + } + public static URI getSourceUri(Class c, String bundleName, String source) throws URISyntaxException { URI uri = new File(source).toURI(); //FIXED: also for TO? -> should work with all now @@ -67,5 +230,125 @@ public class ResourceHandler { } return uri; } + + public static String getContentFromPlugin(String path, String pluginId) throws MalformedURLException, IOException { + URL directURL = URL.of(URI.create("platform:/plugin/"+pluginId+"/"+path), null); + BufferedReader in = new BufferedReader(new InputStreamReader(directURL.openConnection().getInputStream())); + String content = ""; + String line = ""; + while ((line = in.readLine()) != null) { + content+=line+"\n"; + } + in.close(); + return content; + } + + + private static final String TDL_MODEL_NAME = "tdl"; + private static final String HTTP_MODEL_NAME = "http"; + private static final String HTTP_JAVA_NAME = "httpjavamappings"; + private static final String JAVA_MODEL_NAME = "java"; + private static final String[] MODEL_FILE_EXTENSIONS = new String[] { + "tdl", "tdlan2", "tdltx", "tdltxi" + }; + + public static IProject getProjectForResource(Resource resource) { + IWorkspaceRoot ws = org.eclipse.core.resources.ResourcesPlugin.getWorkspace().getRoot(); + org.eclipse.emf.common.util.URI resourceUri = resource.getURI(); + IFile modelFile = null; + if (resourceUri.isPlatformResource()) { + modelFile = ws.getFile(new Path(resourceUri.toPlatformString(true))); + } else if (resourceUri.isFile()) { + // TODO + modelFile = ws.getFile(new Path(resourceUri.toFileString())); +// String uriString = resourceUri.toFileString(); +// java.net.URI uri = new java.net.URI(uriString); +// IFile[] files = ws.findFilesForLocationURI(uri); + } + if (modelFile != null) + return modelFile.getProject(); + return null; + } + + public static Package getTdlPackage(Resource resource) { + return getKnownPackage(resource, TDL_MODEL_NAME); + } + + public static Package getHttpPackage(Resource resource) { + return getKnownPackage(resource, HTTP_MODEL_NAME); + } + + public static Package getJavaPackage(Resource resource) { + return getKnownPackage(resource, JAVA_MODEL_NAME); + } + public static Package getHttpJavaMappingsPackage(Resource resource) { + return getKnownPackage(resource, HTTP_JAVA_NAME); + } + + + private static Package getKnownPackage(Resource resource, String packageName) { + try { + if (!Platform.isRunning()) { + try (Stream files = Files.walk(Paths.get("lib"))) { + // Filter files that match the pattern + Optional path = files.filter(f->f.getFileName().toString().toLowerCase().startsWith(packageName)) + .findFirst(); + if (path.isPresent()) { + java.nio.file.Path p = path.get(); + System.out.println(p); + org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createFileURI(p.toString()); + Resource tdlResource = resource.getResourceSet().getResource(uri, true); + return (Package) tdlResource.getContents().get(0); + } else { + System.out.println("ERROR: " + packageName + " not found!"); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + IProject prj = getProjectForResource(resource); + if (prj != null) { + final Set names = new HashSet<>(); + for (String ext : MODEL_FILE_EXTENSIONS) { + names.add(packageName + "." + ext); + } + FileFinder finder = new FileFinder() { + @Override + protected boolean mathces(IFile file) { + return names.contains(file.getName().toLowerCase()); + } + }; + prj.accept(finder); + if (finder.file != null) { + org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createPlatformResourceURI(finder.file.getFullPath().toString(), true); + Resource tdlResource = resource.getResourceSet().getResource(uri, true); + return (Package) tdlResource.getContents().get(0); + } else { + //TODO: somewhat hacky way to load resources from the library if not found locally + if (Platform.isRunning()) { + Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.library"); + ArrayList packages = new ArrayList<>(); + bundle.findEntries("/","*.tdltx", true).asIterator().forEachRemaining(e-> { + org.eclipse.emf.common.util.URI pURI = org.eclipse.emf.common.util.URI.createURI(e.toString()); + if (names.contains(pURI.lastSegment().toLowerCase())) { + Resource tdlResource = resource.getResourceSet().getResource(pURI, true); + packages.add((Package) tdlResource.getContents().get(0)); + } + }); + return packages.get(0); + } + } + } + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + throw new RuntimeException(e); + } + return null; + } + + + } diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java index 904cd360a6070482f2556e42a9b3eb858ed41bce..3b70c1c831ff265b181845632c54a66f5b675bf8 100644 --- a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/scoping/TDLScopeProvider.java @@ -1,6 +1,5 @@ package org.etsi.mts.tdl.scoping; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; @@ -101,8 +100,13 @@ public class TDLScopeProvider extends AbstractDeclarativeScopeProvider { public Iterator getContainerContents(Element context) { TestDescription td = context.getParentTestDescription(); - if (td == null) - return Collections.emptyIterator(); + if (td == null) { + StructuredTestObjective sto = EcoreUtil2.getContainerOfType(context, StructuredTestObjective.class); + if (sto == null) { + return Collections.emptyIterator(); + } + return sto.eAllContents(); + } return td.eAllContents(); } @@ -362,8 +366,10 @@ public class TDLScopeProvider extends AbstractDeclarativeScopeProvider { return scope; } else if (context.eContainer() instanceof ProcedureCall) { // if (((FunctionCall)context.eContainer()).getFunction().get instanceof StructuredDataInstance) { + if (((ProcedureCall)context.eContainer()).getSignature() != null) { IScope scope = Scopes.scopeFor(((ProcedureCall)context.eContainer()).getSignature().getParameter()); return scope; + } // } } else if (context.eContainer() instanceof DataElementUse) { //TODO: extract and simplify @@ -459,155 +465,196 @@ public class TDLScopeProvider extends AbstractDeclarativeScopeProvider { } } } else if (context instanceof MemberReference) { - if (context.eContainer() instanceof ParameterBinding) { - //TODO: use newly introduced resolveParameterType? - if (((ParameterBinding)context.eContainer()).getReduction().indexOf(context)>0) { - EObject targetContext = ((ParameterBinding)context.eContainer()).getReduction().get(((ParameterBinding)context.eContainer()).getReduction().indexOf(context)-1); - if (((MemberReference)targetContext).getMember()!=null) { - if (((MemberReference)targetContext).getMember().getDataType() instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberReference)targetContext).getMember().getDataType()).allMembers()); - return scope; - } else if (((MemberReference)targetContext).getMember().getDataType() instanceof CollectionDataType) { - DataType itemType = ((CollectionDataType)((MemberReference)targetContext).getMember().getDataType()).getItemType(); - if (itemType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); - return scope; - } - } - } else if (((MemberReference)targetContext).getCollectionIndex() != null) { - DataType dataType = ((ParameterBinding)targetContext.eContainer()).getParameter().getDataType(); - if (dataType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType) dataType).allMembers()); - return scope; - } else if (dataType instanceof CollectionDataType) { - DataType itemType = ((CollectionDataType)dataType).getItemType(); - if (itemType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); - return scope; - } - } - } - } else { - DataType pdt = ((ParameterBinding)context.eContainer()).getParameter().getDataType(); - if (pdt instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType) pdt).allMembers()); - return scope; - } - } - } + List reduction = null; + DataType referenceType = null; if (context.eContainer() instanceof DataUse) { - if (((DataUse)context.eContainer()).getReduction().indexOf(context)>0) { - EObject targetContext = ((DataUse)context.eContainer()).getReduction().get(((DataUse)context.eContainer()).getReduction().indexOf(context)-1); - if (((MemberReference)targetContext).getMember()!=null) { - if (((MemberReference)targetContext).getMember().getDataType() instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberReference)targetContext).getMember().getDataType()).allMembers()); - return scope; - } - } else if (((MemberReference)targetContext).getCollectionIndex()!=null) { - if (targetContext.eContainer() instanceof DataInstanceUse) { - DataInstanceUse dataInstanceUse = (DataInstanceUse)targetContext.eContainer(); - if (dataInstanceUse.getDataType()!=null) { - //TODO:? - } else if (dataInstanceUse.getDataInstance()!=null) { - //TODO: check type - DataType itemType = ((CollectionDataType)dataInstanceUse.getDataInstance().getDataType()).getItemType(); - if (itemType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)itemType).allMembers()); - return scope; - } - } - } else if (targetContext.eContainer() instanceof DataElementUse) { - DataElementUse dataElementUse = (DataElementUse)targetContext.eContainer(); - DataType resolvedDataType = dataElementUse.resolveDataType(); - if (resolvedDataType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); - return scope; - } else if (resolvedDataType instanceof CollectionDataType) { - DataType itemType = ((CollectionDataType)resolvedDataType).getItemType(); - if (itemType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); - return scope; + reduction = ((DataUse) context.eContainer()).getReduction(); + referenceType = ((DataUse) context.eContainer()).resolveBaseDataType(); + } else if (context.eContainer() instanceof ParameterBinding) { + reduction = ((ParameterBinding) context.eContainer()).getReduction(); + referenceType = ((ParameterBinding) context.eContainer()).getParameter().getDataType(); + } + if (reduction != null && !reduction.isEmpty()) { + int rIndex = reduction.indexOf(context); + if (rIndex > 0) { + MemberReference preceding = reduction.get(rIndex - 1); + if (preceding.getMember()!=null) { + referenceType = preceding.getMember().getDataType(); + } else { + if (rIndex > 1) { + preceding = reduction.get(rIndex - 2); + if (preceding.getMember()!=null) { + referenceType = preceding.getMember().getDataType(); + if (referenceType instanceof CollectionDataType) { + referenceType = ((CollectionDataType) referenceType).getItemType(); } - + } else { + //TODO: handle, e.g. first reference + referenceType = ((DataUse)context.eContainer()).resolveBaseDataType(); } - + } else { + //TODO: handle, e.g. first reference + referenceType = ((DataUse)context.eContainer()).resolveBaseDataType(); } - //TODO: handle other scenarios? - } - } - } - if (context.eContainer() instanceof DataInstanceUse) { - if (((DataInstanceUse)context.eContainer()).getDataInstance() instanceof StructuredDataInstance) { - DataInstance dataInstance = ((DataInstanceUse)context.eContainer()).getDataInstance(); - if (dataInstance instanceof StructuredDataInstance && dataInstance.getDataType() instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)dataInstance).getDataType()).allMembers()); - return scope; - } - } - } else if (context.eContainer() instanceof FunctionCall) { - if (((FunctionCall)context.eContainer()).getFunction().getReturnType() instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)((FunctionCall)context.eContainer()).getFunction().getReturnType()).allMembers()); - return scope; - } - } else if (context.eContainer() instanceof FormalParameterUse) { - if (((FormalParameterUse)context.eContainer()).getParameter().getDataType() instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameterUse)context.eContainer()).getParameter().getDataType()).allMembers()); - return scope; - } - } else if (context.eContainer() instanceof VariableUse) { - if (((VariableUse)context.eContainer()).getVariable().getDataType() instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)((VariableUse)context.eContainer()).getVariable().getDataType()).allMembers()); - return scope; } - } else if (context.eContainer() instanceof DataElementUse) { - NamedElement dataElement = ((DataElementUse) context.eContainer()).getDataElement(); - //TODO: duplicated from above ->extract - if (dataElement instanceof org.etsi.mts.tdl.Function) { - DataType returnType = ((org.etsi.mts.tdl.Function)dataElement).getReturnType(); - if (returnType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)returnType).allMembers()); - return scope; - } - } else if (dataElement instanceof FormalParameter) { - IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameter) dataElement).getDataType()).allMembers()); - return scope; - } else if (dataElement instanceof StructuredDataInstance) { - if (((StructuredDataInstance) dataElement).getDataType() instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance) dataElement).getDataType()).allMembers()); - return scope; - } - } else if (dataElement instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)dataElement).allMembers()); - return scope; - } else if (dataElement == null) { - //TODO: use more widely! Will save a lot of the code in here... - DataType resolvedDataType = ((DataElementUse)context.eContainer()).resolveDataType(); - if (resolvedDataType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); - return scope; - } - } - } else if (context.eContainer() instanceof LiteralValueUse) { - DataType resolvedDataType = ((LiteralValueUse)context.eContainer()).resolveDataType(); - if (resolvedDataType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); - return scope; - } - } else if (context.eContainer() instanceof CastDataUse) { - DataType resolvedDataType = ((CastDataUse)context.eContainer()).resolveDataType(); - if (resolvedDataType instanceof StructuredDataType) { - IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); - return scope; - } - } else if (context.eContainer() instanceof PredefinedFunctionCall) { -// DataType resolvedDataType = ((PredefinedFunctionCall)context.eContainer()).resolveDataType(); + } + if (referenceType instanceof CollectionDataType) { + referenceType = ((CollectionDataType) referenceType).getItemType(); + } + if (referenceType instanceof StructuredDataType) { + IScope scope = Scopes.scopeFor(((StructuredDataType) referenceType).allMembers()); + return scope; + } +// if (context.eContainer() instanceof ParameterBinding) { +// //TODO: use newly introduced resolveParameterType? +// if (((ParameterBinding)context.eContainer()).getReduction().indexOf(context)>0) { +// EObject targetContext = ((ParameterBinding)context.eContainer()).getReduction().get(((ParameterBinding)context.eContainer()).getReduction().indexOf(context)-1); +// if (((MemberReference)targetContext).getMember()!=null) { +// if (((MemberReference)targetContext).getMember().getDataType() instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberReference)targetContext).getMember().getDataType()).allMembers()); +// return scope; +// } else if (((MemberReference)targetContext).getMember().getDataType() instanceof CollectionDataType) { +// DataType itemType = ((CollectionDataType)((MemberReference)targetContext).getMember().getDataType()).getItemType(); +// if (itemType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); +// return scope; +// } +// } +// } else if (((MemberReference)targetContext).getCollectionIndex() != null) { +// DataType dataType = ((ParameterBinding)targetContext.eContainer()).getParameter().getDataType(); +// if (dataType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType) dataType).allMembers()); +// return scope; +// } else if (dataType instanceof CollectionDataType) { +// DataType itemType = ((CollectionDataType)dataType).getItemType(); +// if (itemType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); +// return scope; +// } +// } +// } +// } else { +// DataType pdt = ((ParameterBinding)context.eContainer()).getParameter().getDataType(); +// if (pdt instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType) pdt).allMembers()); +// return scope; +// } +// } +// } +// if (context.eContainer() instanceof DataUse) { +// if (((DataUse)context.eContainer()).getReduction().indexOf(context)>0) { +// EObject targetContext = ((DataUse)context.eContainer()).getReduction().get(((DataUse)context.eContainer()).getReduction().indexOf(context)-1); +// if (((MemberReference)targetContext).getMember()!=null) { +// if (((MemberReference)targetContext).getMember().getDataType() instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)((MemberReference)targetContext).getMember().getDataType()).allMembers()); +// return scope; +// } +// } else if (((MemberReference)targetContext).getCollectionIndex()!=null) { +// if (targetContext.eContainer() instanceof DataInstanceUse) { +// DataInstanceUse dataInstanceUse = (DataInstanceUse)targetContext.eContainer(); +// if (dataInstanceUse.getDataType()!=null) { +// //TODO:? +// } else if (dataInstanceUse.getDataInstance()!=null) { +// //TODO: check type +// DataType itemType = ((CollectionDataType)dataInstanceUse.getDataInstance().getDataType()).getItemType(); +// if (itemType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)itemType).allMembers()); +// return scope; +// } +// } +// } else if (targetContext.eContainer() instanceof DataElementUse) { +// DataElementUse dataElementUse = (DataElementUse)targetContext.eContainer(); +// DataType resolvedDataType = dataElementUse.resolveDataType(); +// if (resolvedDataType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); +// return scope; +// } else if (resolvedDataType instanceof CollectionDataType) { +// DataType itemType = ((CollectionDataType)resolvedDataType).getItemType(); +// if (itemType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType) itemType).allMembers()); +// return scope; +// } +// +// } +// +// } +// //TODO: handle other scenarios? +// +// } +// } +// } +// if (context.eContainer() instanceof DataInstanceUse) { +// if (((DataInstanceUse)context.eContainer()).getDataInstance() instanceof StructuredDataInstance) { +// DataInstance dataInstance = ((DataInstanceUse)context.eContainer()).getDataInstance(); +// if (dataInstance instanceof StructuredDataInstance && dataInstance.getDataType() instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance)dataInstance).getDataType()).allMembers()); +// return scope; +// } +// } +// } else if (context.eContainer() instanceof FunctionCall) { +// if (((FunctionCall)context.eContainer()).getFunction().getReturnType() instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)((FunctionCall)context.eContainer()).getFunction().getReturnType()).allMembers()); +// return scope; +// } +// } else if (context.eContainer() instanceof FormalParameterUse) { +// if (((FormalParameterUse)context.eContainer()).getParameter().getDataType() instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameterUse)context.eContainer()).getParameter().getDataType()).allMembers()); +// return scope; +// } +// } else if (context.eContainer() instanceof VariableUse) { +// if (((VariableUse)context.eContainer()).getVariable().getDataType() instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)((VariableUse)context.eContainer()).getVariable().getDataType()).allMembers()); +// return scope; +// } +// } else if (context.eContainer() instanceof DataElementUse) { +// NamedElement dataElement = ((DataElementUse) context.eContainer()).getDataElement(); +// //TODO: duplicated from above ->extract +// if (dataElement instanceof org.etsi.mts.tdl.Function) { +// DataType returnType = ((org.etsi.mts.tdl.Function)dataElement).getReturnType(); +// if (returnType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)returnType).allMembers()); +// return scope; +// } +// } else if (dataElement instanceof FormalParameter) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)((FormalParameter) dataElement).getDataType()).allMembers()); +// return scope; +// } else if (dataElement instanceof StructuredDataInstance) { +// if (((StructuredDataInstance) dataElement).getDataType() instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)((StructuredDataInstance) dataElement).getDataType()).allMembers()); +// return scope; +// } +// } else if (dataElement instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)dataElement).allMembers()); +// return scope; +// } else if (dataElement == null) { +// //TODO: use more widely! Will save a lot of the code in here... +// DataType resolvedDataType = ((DataElementUse)context.eContainer()).resolveDataType(); +// if (resolvedDataType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); +// return scope; +// } +// } +// } else if (context.eContainer() instanceof LiteralValueUse) { +// DataType resolvedDataType = ((LiteralValueUse)context.eContainer()).resolveDataType(); // if (resolvedDataType instanceof StructuredDataType) { // IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); // return scope; // } - } else { - } +// } else if (context.eContainer() instanceof CastDataUse) { +// DataType resolvedDataType = ((CastDataUse)context.eContainer()).resolveDataType(); +// if (resolvedDataType instanceof StructuredDataType) { +// IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); +// return scope; +// } +// } else if (context.eContainer() instanceof PredefinedFunctionCall) { +//// DataType resolvedDataType = ((PredefinedFunctionCall)context.eContainer()).resolveDataType(); +//// if (resolvedDataType instanceof StructuredDataType) { +//// IScope scope = Scopes.scopeFor(((StructuredDataType)resolvedDataType).allMembers()); +//// return scope; +//// } +// } else { +// } } else if (context instanceof ValueAssignment) { IScope scope = Scopes.scopeFor(((ProcedureCall)context.eContainer().eContainer()).getSignature().getParameter()); return scope; diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/AbstractTranslator.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/AbstractTranslator.java index 0268522a6301da84ba942c88f967cd3bc2991471..3e5055755bd39715a54c1252fbcc83c3294c747e 100644 --- a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/AbstractTranslator.java +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/AbstractTranslator.java @@ -9,6 +9,7 @@ import java.util.TreeMap; import java.util.function.Predicate; import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.EcoreUtil2; import org.etsi.mts.tdl.Annotation; @@ -36,7 +37,13 @@ import org.etsi.mts.tdl.StructuredDataType; import org.etsi.mts.tdl.tdlFactory; import org.etsi.mts.tdl.tdlPackage; +import com.google.inject.Inject; +import com.google.inject.Injector; + public abstract class AbstractTranslator { + @Inject + protected Injector injector; + protected DataResourceMapping drm; protected DataResourceMapping drmTarget; private Package generatedPackage; @@ -48,6 +55,7 @@ public abstract class AbstractTranslator { protected boolean fullPrefix = false; protected String sourceMappingTag = "SOURCE_MAPPING"; protected String targetMappingTag = "TARGET_MAPPING"; + protected String limit = null; public AbstractTranslator() { super(); @@ -126,8 +134,13 @@ public abstract class AbstractTranslator { e.setExtending(superType); if (type instanceof SimpleDataType) ((SimpleDataType) type).setExtension(e); - if (type instanceof StructuredDataType) + if (type instanceof StructuredDataType) { ((StructuredDataType) type).getExtension().add(e); + //prune members from supertype to avoid duplicates + ((StructuredDataType) type).getMember() + .removeIf(m -> ((StructuredDataType)superType).allMembers().stream() + .anyMatch(sm -> sm.getName().equals(m.getName()))); + } } @@ -198,6 +211,13 @@ public abstract class AbstractTranslator { T content = null; if (optional.isPresent()) { content = (T) optional.get(); + } else { + EClass extClass = tdlPackage.eINSTANCE.getExtension(); + Optional extension = container.eContents().stream() + .filter(e->extClass.isInstance(e)) + .findFirst(); + if (extension.isPresent()) + return findContentWithName(name, ((Extension)extension.get()).getExtending(), targetType); } return content; } @@ -340,4 +360,8 @@ public abstract class AbstractTranslator { names.add(newName); } + public void setLimit(String limit) { + this.limit = limit; + } + } \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/Converter.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/Converter.java new file mode 100644 index 0000000000000000000000000000000000000000..4fb7e0ca259dba827eac9b5b3247612a3b8823a5 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/Converter.java @@ -0,0 +1,29 @@ +package org.etsi.mts.tdl.transform; + +import java.util.List; +import java.util.TreeMap; + +public interface Converter { + public String getExtension(); + public String processToString(String inputPath, String outputPath); + default public String processToString(List inputPaths, String outputPath) { + String content = "Package Imported { \n"; + for (String path : inputPaths) { + content += processToString(path, outputPath); + } + content +="}"; + return content; + } + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping); + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping, boolean inline); + + public static Converter getConverter(String type) { + return ServiceProvider.getService(Converter.class.getName(), type); + } + + //only in Eclipse + public static TreeMap getConverters() { + return ServiceProvider.getServices(Converter.class.getName()); + } + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ConverterNotAvailable.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ConverterNotAvailable.java new file mode 100644 index 0000000000000000000000000000000000000000..3f4c0447068db3ad2c298f19164d05e55f79cce3 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ConverterNotAvailable.java @@ -0,0 +1,38 @@ +package org.etsi.mts.tdl.transform; + +import java.util.List; + +public class ConverterNotAvailable implements Converter { + private String type; + private String content = ""; + + public ConverterNotAvailable(String type) { + this.type = type; + this.content = "Note: \"Converter not available: "+type+"\"\nPackage imported {}"; + } + @Override + public String getExtension() { + return "n.a."; + } + + @Override + public String processToString(String inputPath, String outputPath) { + return content; + } + + @Override + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) { + return processToString(inputPath, outputPath); + } + @Override + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping, + boolean inline) { + return processToString(inputPath, outputPath); + } + @Override + public String processToString(List inputPaths, String outputPath) { + return processToString("", outputPath); + } + + +} diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/Generator.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/Generator.java new file mode 100644 index 0000000000000000000000000000000000000000..f6710478c91bec530be20264425453dd923bfa8f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/Generator.java @@ -0,0 +1,6 @@ +package org.etsi.mts.tdl.transform; + + +public interface Generator extends Converter { + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/HttpFileClient.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/HttpFileClient.java new file mode 100644 index 0000000000000000000000000000000000000000..43872ad712d5917445e05aed7db05eb5585876ed --- /dev/null +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/HttpFileClient.java @@ -0,0 +1,177 @@ +package org.etsi.mts.tdl.transform; +import java.io.*; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.*; +import java.util.*; + + +public class HttpFileClient { + + private static final String CRLF = "\r\n"; + private static final String BOUNDARY = "----WebKitFormBoundary" + System.currentTimeMillis(); + + /** + * Response container holding the JSON data and additional metadata + */ + public static class ApiResponse { + private final String jsonBody; + private final int statusCode; + private final Map> headers; + + public ApiResponse(String jsonBody, int statusCode, Map> headers) { + this.jsonBody = jsonBody; + this.statusCode = statusCode; + this.headers = headers; + } + + public String getJsonBody() { return jsonBody; } + public int getStatusCode() { return statusCode; } + public Map> getHeaders() { return headers; } + public String getHeader(String name) { + List values = headers.get(name); + return values != null && !values.isEmpty() ? values.get(0) : null; + } + } + + /** + * Upload one or more files via POST to the specified URL + * + * @param url API endpoint URL + * @param files Map of field names to file paths + * @param additionalFields Optional text fields to include in the request + * @return ApiResponse containing JSON and metadata + */ + public static ApiResponse uploadFiles(String url, Map files, + Map additionalFields) throws IOException { + log("CLIENT: Starting upload to " + url); + URL apiUrl = new URL(url); + HttpURLConnection conn = (HttpURLConnection) apiUrl.openConnection(); + + try { + // Configure connection + log("CLIENT: Configuring connection"); + conn.setRequestMethod("POST"); + conn.setDoOutput(true); + conn.setDoInput(true); + conn.setUseCaches(false); + conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); + conn.setRequestProperty("Accept", "application/json"); + conn.setRequestProperty("Connection", "Keep-Alive"); + conn.setChunkedStreamingMode(8192); // Use chunked mode to avoid hanging + + log("CLIENT: Getting output stream"); + // Write multipart request body + try (OutputStream out = conn.getOutputStream()) { + log("CLIENT: Got output stream, writing data"); + + // Add additional text fields if provided + if (additionalFields != null) { + for (Map.Entry field : additionalFields.entrySet()) { + log("CLIENT: Writing field: " + field.getKey()); + writeField(out, field.getKey(), field.getValue()); + } + } + + // Add files + for (Map.Entry file : files.entrySet()) { + log("CLIENT: Writing file: " + file.getValue().getFileName()); +// writeFile(out, file.getKey(), file.getValue()); + writeFile(out, "files[]", file.getValue()); + } + + // End multipart request + log("CLIENT: Writing end boundary"); + String endBoundary = "--" + BOUNDARY + "--" + CRLF; + out.write(endBoundary.getBytes(StandardCharsets.UTF_8)); + out.flush(); + log("CLIENT: Finished writing request body"); + } + + // Read response + log("CLIENT: Getting response code"); + int statusCode = conn.getResponseCode(); + log("CLIENT: Response code: " + statusCode); + InputStream responseStream = statusCode >= 400 ? conn.getErrorStream() : conn.getInputStream(); + + String jsonResponse = readInputStream(responseStream); +// log("CLIENT: Got response: " + jsonResponse); + Map> headers = conn.getHeaderFields(); + + return new ApiResponse(jsonResponse, statusCode, headers); + + } finally { + conn.disconnect(); + } + } + + private static void writeField(OutputStream out, String name, String value) throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append("--").append(BOUNDARY).append(CRLF); + sb.append("Content-Disposition: form-data; name=\"").append(name).append("\"").append(CRLF); + sb.append(CRLF); + sb.append(value).append(CRLF); + out.write(sb.toString().getBytes(StandardCharsets.UTF_8)); + } + + private static void writeFile(OutputStream out, String fieldName, Path filePath) throws IOException { + String fileName = filePath.getFileName().toString(); + + StringBuilder sb = new StringBuilder(); + sb.append("--").append(BOUNDARY).append(CRLF); + sb.append("Content-Disposition: form-data; name=\"") + .append(fieldName).append("\"; filename=\"") + .append(fileName).append("\"").append(CRLF); + sb.append("Content-Type: ").append(probeContentType(filePath)).append(CRLF); + sb.append(CRLF); + out.write(sb.toString().getBytes(StandardCharsets.UTF_8)); + + // Write file bytes + Files.copy(filePath, out); + + out.write(CRLF.getBytes(StandardCharsets.UTF_8)); + } + + /** + * Upload a single file + */ + public static ApiResponse uploadFile(String url, String fieldName, Path filePath) throws IOException { + Map files = new HashMap<>(); + files.put(fieldName, filePath); + return uploadFiles(url, files, null); + } + + /** + * Probe content type or return default + */ + private static String probeContentType(Path path) { + try { + String type = Files.probeContentType(path); + return type != null ? type : "application/octet-stream"; + } catch (IOException e) { + return "application/octet-stream"; + } + } + + /** + * Read input stream to string + */ + private static String readInputStream(InputStream is) throws IOException { + if (is == null) return ""; + + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(is, StandardCharsets.UTF_8))) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + } + return sb.toString().trim(); + } + } + + + public static void log(String message) { + System.out.println(message); + } +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ProtocolServerBridge.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ProtocolServerBridge.java new file mode 100644 index 0000000000000000000000000000000000000000..120a0dfcd7d112b05f836400ec97190d5fb919f1 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ProtocolServerBridge.java @@ -0,0 +1,65 @@ +package org.etsi.mts.tdl.transform; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.etsi.mts.tdl.transform.HttpFileClient.ApiResponse; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; + + +public class ProtocolServerBridge { + public String convertASN1toTDLRemote(String uri, List asnFilePaths, String targetPath) { + Map files = new HashMap<>(); + int i = 1; + for (String p : asnFilePaths) { + files.put("files"+i, Paths.get(p)); + i++; + } + + Map fields = new HashMap<>(); +// fields.put("backend", "titan"); +// fields.put("command", "compiler"); + fields.put("format", "tdl"); + + try { + ApiResponse response = HttpFileClient.uploadFiles( + uri, + files, + fields + ); + log("\nASN.1 files submitted..:"); + log("Status: " + response.getStatusCode()); + String body = response.getJsonBody(); + JsonObject jsonElement = JsonParser.parseString(body).getAsJsonArray().get(0).getAsJsonObject(); + String tdl = jsonElement.get("tdl").getAsString(); + + //TODO: get right part of body + System.out.println("Response: \n" + tdl); + //Files.writeString(Path.of(targetPath), tdl, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); + //TODO: handle + return tdl; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return ""; + } + + private void log(String message) { + System.out.println(message); + } + +} diff --git a/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ServiceProvider.java b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ServiceProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..e786b584470db4283950c1c3e987a1b486f2e139 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/transform/ServiceProvider.java @@ -0,0 +1,51 @@ +package org.etsi.mts.tdl.transform; + +import java.util.TreeMap; + +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +public interface ServiceProvider { + public static T getService(String service, String type) { + if (Platform.isRunning()) { + try { + Bundle targetBundle = Platform.getBundle(type); + if (targetBundle != null && targetBundle.getState() != Bundle.ACTIVE) { + targetBundle.start(); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + return (T) getServices(service).getOrDefault(type, new ConverterNotAvailable(type)); + } + + public static TreeMap getServices(String name) { + TreeMap map = new TreeMap<>(); + if (Platform.isRunning()) { + try { + Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.common"); + if (bundle.getState() != Bundle.ACTIVE) { + bundle.start(); + } + BundleContext context = bundle.getBundleContext(); + ServiceReference ref[] = context.getServiceReferences(name, "(type=*)"); +// ref = context.getServiceReferences(Converter.class.getName(), null); + if (ref != null) { + for(int i = 0; i < ref.length; i++) { + map.put((String)ref[i].getProperty("type"), ((T)context.getService(ref[i]))); + } + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return map; + } + +} diff --git a/plugins/org.etsi.mts.tdl.constraints.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.constraints.ui/META-INF/MANIFEST.MF index 60165ba221d44c51139e45f105636a5a6068e938..bca5b73f7810ebb7f792f527b2e2562aae731c34 100644 --- a/plugins/org.etsi.mts.tdl.constraints.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.constraints.ui/META-INF/MANIFEST.MF @@ -12,15 +12,6 @@ Require-Bundle: org.eclipse.ui, org.eclipse.ui.ide;bundle-version="3.5.0", org.eclipse.ui.workbench, org.etsi.mts.tdl.constraints, - org.eclipse.epsilon.common, - org.eclipse.epsilon.emc.emf, - org.eclipse.epsilon.eol.engine, - org.eclipse.epsilon.erl.engine, - org.eclipse.epsilon.evl.engine, - org.eclipse.epsilon.evl.emf.validation, - org.eclipse.epsilon.etl.engine, - org.eclipse.epsilon.profiling, - org.eclipse.epsilon.eol.tools, org.eclipse.ocl.xtext.completeocl.ui, org.eclipse.ocl.xtext.essentialocl.ui, com.google.inject, diff --git a/plugins/org.etsi.mts.tdl.constraints.ui/src/org/etsi/mts/tdl/constraints/ui/handlers/ToggleValidationHandler.java b/plugins/org.etsi.mts.tdl.constraints.ui/src/org/etsi/mts/tdl/constraints/ui/handlers/ToggleValidationHandler.java index 1baf2970c33d6f2fa2b5f05ecf87f67ab9bc0245..77db698cd207dfa6ede9b0c6e89dd307b757af61 100644 --- a/plugins/org.etsi.mts.tdl.constraints.ui/src/org/etsi/mts/tdl/constraints/ui/handlers/ToggleValidationHandler.java +++ b/plugins/org.etsi.mts.tdl.constraints.ui/src/org/etsi/mts/tdl/constraints/ui/handlers/ToggleValidationHandler.java @@ -10,14 +10,14 @@ import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EValidator; import org.eclipse.emf.ecore.util.EObjectValidator; -import org.eclipse.epsilon.evl.emf.validation.CompositeEValidator; -import org.eclipse.epsilon.evl.emf.validation.EvlValidator; +//import org.eclipse.epsilon.evl.emf.validation.CompositeEValidator; +//import org.eclipse.epsilon.evl.emf.validation.EvlValidator; import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.etsi.mts.tdl.tdlPackage; public class ToggleValidationHandler extends AbstractHandler { private static boolean initialised; - private static EvlValidator evlValidator; +// private static EvlValidator evlValidator; //TODO: for some reason seems to hang now.. @Override @@ -47,21 +47,21 @@ public class ToggleValidationHandler extends AbstractHandler { public static void stop() { EPackage ePackage = tdlPackage.eINSTANCE; EValidator existingValidator = EValidator.Registry.INSTANCE.getEValidator(ePackage); - if (existingValidator instanceof CompositeEValidator) { - //TODO: check for evl validators? - ((CompositeEValidator) existingValidator).getDelegates().remove(evlValidator); - Collection delegates = ((CompositeEValidator) existingValidator).getDelegates(); - //TODO: make more robust - delegates.removeIf(d -> d instanceof EvlValidator); - } else { - if (existingValidator == null) { - existingValidator = EObjectValidator.INSTANCE; - } - CompositeEValidator newValidator = new CompositeEValidator(); - newValidator.getDelegates().add(existingValidator); - newValidator.getDelegates().add(evlValidator); - EValidator.Registry.INSTANCE.put(ePackage, newValidator); - } +// if (existingValidator instanceof CompositeEValidator) { +// //TODO: check for evl validators? +// ((CompositeEValidator) existingValidator).getDelegates().remove(evlValidator); +// Collection delegates = ((CompositeEValidator) existingValidator).getDelegates(); +// //TODO: make more robust +// delegates.removeIf(d -> d instanceof EvlValidator); +// } else { +// if (existingValidator == null) { +// existingValidator = EObjectValidator.INSTANCE; +// } +// CompositeEValidator newValidator = new CompositeEValidator(); +// newValidator.getDelegates().add(existingValidator); +// newValidator.getDelegates().add(evlValidator); +// EValidator.Registry.INSTANCE.put(ePackage, newValidator); +// } } @@ -85,10 +85,10 @@ public class ToggleValidationHandler extends AbstractHandler { //TODO: try out extension point integration //TODO: try out fixes -> can they be in a separate module? //TODO: add other constraints for TO/TC - evlValidator = new EvlValidator( - evlScriptURI, modelName , ePackage.getNsURI(), bundleId); - - evlValidator.setShowErrorDialog(false); +// evlValidator = new EvlValidator( +// evlScriptURI, modelName , ePackage.getNsURI(), bundleId); +// +// evlValidator.setShowErrorDialog(false); //TODO: extract to optional on demand / auto validation //TODO: this brings all the epsilon dependencies here as well //-> effectively requires constraints to be installed.. shall be plugged in ideally.. @@ -101,17 +101,17 @@ public class ToggleValidationHandler extends AbstractHandler { //TODO: reorganise and reuse (from TDLtxValidator, shall migrate local Validator as well) private static void registerValidator(EPackage ePackage) { EValidator existingValidator = EValidator.Registry.INSTANCE.getEValidator(ePackage); - if (existingValidator instanceof CompositeEValidator) { - ((CompositeEValidator) existingValidator).getDelegates().add(evlValidator); - } else { - if (existingValidator == null) { - existingValidator = EObjectValidator.INSTANCE; - } - CompositeEValidator newValidator = new CompositeEValidator(); - newValidator.getDelegates().add(existingValidator); - newValidator.getDelegates().add(evlValidator); - EValidator.Registry.INSTANCE.put(ePackage, newValidator); - } +// if (existingValidator instanceof CompositeEValidator) { +// ((CompositeEValidator) existingValidator).getDelegates().add(evlValidator); +// } else { +// if (existingValidator == null) { +// existingValidator = EObjectValidator.INSTANCE; +// } +// CompositeEValidator newValidator = new CompositeEValidator(); +// newValidator.getDelegates().add(existingValidator); +// newValidator.getDelegates().add(evlValidator); +// EValidator.Registry.INSTANCE.put(ePackage, newValidator); +// } } } diff --git a/plugins/org.etsi.mts.tdl.constraints.ui/src/org/etsi/mts/tdl/constraints/ui/handlers/ValidationHandler.java b/plugins/org.etsi.mts.tdl.constraints.ui/src/org/etsi/mts/tdl/constraints/ui/handlers/ValidationHandler.java index 5f9af791bb32ace51992e3ebbac600fa7bf08d3d..59c28d13953751fb25d68c168803d74d6e6e7504 100644 --- a/plugins/org.etsi.mts.tdl.constraints.ui/src/org/etsi/mts/tdl/constraints/ui/handlers/ValidationHandler.java +++ b/plugins/org.etsi.mts.tdl.constraints.ui/src/org/etsi/mts/tdl/constraints/ui/handlers/ValidationHandler.java @@ -17,7 +17,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.epsilon.evl.execute.UnsatisfiedConstraint; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; @@ -83,22 +82,22 @@ public class ValidationHandler extends AbstractHandler { Validator validator = new Validator(); String messages = ""; try { - List violations = validator.validate(r); - for (UnsatisfiedConstraint v : violations) { - messages += v.getMessage()+"\n"; - //TODO: this can only work with XtextResources - if (((EObject) v.getInstance()).eResource() instanceof XtextResource) { - ICompositeNode node = NodeModelUtils.findActualNodeFor((EObject) v.getInstance()); - String text = "\tLine "+node.getStartLine()+"-"+node.getEndLine()+ ":\n\t"+node.getText().trim(); - messages += " "+text+"\n\n"; - } else { - //TODO: dump tree-based representation? - } - } +// List violations = validator.validate(r); +// for (UnsatisfiedConstraint v : violations) { +// messages += v.getMessage()+"\n"; +// //TODO: this can only work with XtextResources +// if (((EObject) v.getInstance()).eResource() instanceof XtextResource) { +// ICompositeNode node = NodeModelUtils.findActualNodeFor((EObject) v.getInstance()); +// String text = "\tLine "+node.getStartLine()+"-"+node.getEndLine()+ ":\n\t"+node.getText().trim(); +// messages += " "+text+"\n\n"; +// } else { +// //TODO: dump tree-based representation? +// } +// } - if (violations.size() == 0) { - messages = "No violations!"; - } +// if (violations.size() == 0) { +// messages = "No violations!"; +// } } catch (Exception e) { messages = "An error occurred:" + e.getMessage().replaceAll("\n.+epsilon/", "\n at (epsilon/"); diff --git a/plugins/org.etsi.mts.tdl.constraints/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.constraints/META-INF/MANIFEST.MF index 8f0100f63aa4552059f7aff399b6d83d2cd7153d..3bc1350bc3ee8e7d6dbf0188c2c54d1588789951 100644 --- a/plugins/org.etsi.mts.tdl.constraints/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.constraints/META-INF/MANIFEST.MF @@ -4,21 +4,11 @@ Bundle-Name: Constraints Bundle-SymbolicName: org.etsi.mts.tdl.constraints;singleton:=true Bundle-Version: 1.0.0.qualifier Require-Bundle: org.eclipse.emf.common, - org.eclipse.epsilon.common, - org.eclipse.epsilon.emc.emf, - org.eclipse.epsilon.eol.engine, - org.eclipse.epsilon.erl.engine, - org.eclipse.epsilon.evl.engine, - org.eclipse.epsilon.evl.emf.validation, - org.eclipse.epsilon.etl.engine, - org.eclipse.epsilon.profiling, - org.eclipse.epsilon.eol.tools, org.eclipse.core.runtime, org.eclipse.emf.ecore;visibility:=reexport, org.eclipse.emf.ecore.xmi, org.etsi.mts.tdl.model, org.etsi.mts.tdl.common, org.eclipse.xtext, - org.eclipse.epsilon.common.dt, org.eclipse.ocl.xtext.completeocl Export-Package: org.etsi.mts.tdl.constraints.evl diff --git a/plugins/org.etsi.mts.tdl.constraints/ocl/tdl-constraints.ocl b/plugins/org.etsi.mts.tdl.constraints/ocl/tdl-constraints.ocl index 6bc9670bce411dcbc698b997ae450d48a4ef8175..d46ab8453d1365d4b3a067038d440d7e0c73411c 100644 --- a/plugins/org.etsi.mts.tdl.constraints/ocl/tdl-constraints.ocl +++ b/plugins/org.etsi.mts.tdl.constraints/ocl/tdl-constraints.ocl @@ -700,9 +700,9 @@ context AlternativeBehaviour inv AlternativeBlocksComponent ('If the containing \'TestDescription\' is locally ordered then all \'Block\'s shall start with a tester-input event of the same \'ComponentInstance\'. ' + self.toString()): let initial = self.block.behaviour->first() in Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) ->size() = 1 or not self.getParentTestDescription().isLocallyOrdered @@ -710,9 +710,9 @@ context AlternativeBehaviour inv AlternativeBehaviourParticipation ('If the \'AlternativeBehaviour\' is contained in a locally ordered \'TestDescription\' then no other tester \'ComponentInstance\' shall participate in any block than the target of the first tester-input event and \'ComponentInstance\'s participating in blocks of contained \'OptionalBehaviour\'s. ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance), + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance), nonOptionalBlocks = self.block->closure( b | b.behaviour->reject(oclIsKindOf(OptionalBehaviour)) ->select(oclIsKindOf(SingleCombinedBehaviour)).oclAsType(SingleCombinedBehaviour).block @@ -729,9 +729,9 @@ context AlternativeBehaviour inv OptionalAlternativeBehaviour ('A block of an \'AlternativeBehaviour\' if the containing \'TestDescription\' is locally ordered, shall only contain \'OptionalBehaviour\'(s) whose source \'ComponentInstance\' is the same as the target of the first tester-input event of that \'Block\'. ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) in self.block.behaviour->select(oclIsKindOf(OptionalBehaviour)) .oclAsType(OptionalBehaviour).block ->first().oclAsType(Interaction).sourceGate.component->forAll(c | targetComponent->includes(c)) @@ -778,9 +778,9 @@ context ExceptionalBehaviour inv ExceptionalGuardedandTargetComponent ('If the containing \'TestDescription\' is locally ordered and guardedComponent is specified then the \'Block\'s shall start with tester-input event of the same \'ComponentInstance\' as specified in guardedComponent. ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) in guardedComponent->includesAll(targetComponent) or not self.getParentTestDescription().isLocallyOrdered @@ -790,9 +790,9 @@ context ExceptionalBehaviour inv ExceptionalBehaviourParticipation ('If the \'ExceptionalBehaviour\' is contained in a locally ordered \'TestDescription\' then no other tester \'ComponentInstance\' shall participate in any block than the target of the first tester-input event and \'ComponentInstance\'s participating in blocks of contained \'OptionalBehaviour\'s . ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance), + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance), nonOptionalBlocks = self.block->closure( b | b.behaviour->reject(oclIsKindOf(OptionalBehaviour)) ->select(oclIsKindOf(SingleCombinedBehaviour)).oclAsType(SingleCombinedBehaviour).block @@ -809,12 +809,12 @@ context ExceptionalBehaviour inv OptionalExceptionalBehaviour ('A block of an \'ExceptionalBehaviour\' if the containing \'TestDescription\' is locally ordered, shall only contain \'OptionalBehaviour\'(s) whose source \'ComponentInstance\' is the same as the target of the first tester-input event of that \'Block\'. ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) in - self.block.behaviour->select(oclIsKindOf(OptionalBehaviour)).oclAsType(OptionalBehaviour).block - ->first().oclAsType(Interaction).sourceGate.component->forAll(c | targetComponent->includes(c)) + self.block.behaviour->select(oclIsKindOf(OptionalBehaviour)).oclAsType(OptionalBehaviour)->forAll(op | op.block->asSequence() + ->first().oclAsType(Interaction).sourceGate.component->forAll(c | targetComponent->includes(c))) or not self.getParentTestDescription().isLocallyOrdered diff --git a/plugins/org.etsi.mts.tdl.constraints/plugin.xml b/plugins/org.etsi.mts.tdl.constraints/plugin.xml index 914dcd5f61226d64962457a2a168975ceeb6182f..4a60770b8bedf30ad6aa770fdb7e4fa148d289ab 100644 --- a/plugins/org.etsi.mts.tdl.constraints/plugin.xml +++ b/plugins/org.etsi.mts.tdl.constraints/plugin.xml @@ -1,6 +1,7 @@ + diff --git a/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/Validator.java b/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/Validator.java index 3558f81006465eebc761e4c8189333085646f2b7..cea66487f024ccfc388fe6f23230316ea7a08c91 100644 --- a/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/Validator.java +++ b/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/Validator.java @@ -42,30 +42,6 @@ import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EObjectValidator; import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.epsilon.common.parse.Region; -import org.eclipse.epsilon.common.parse.problem.ParseProblem; -import org.eclipse.epsilon.common.util.StringProperties; -import org.eclipse.epsilon.emc.emf.EmfModel; -import org.eclipse.epsilon.emc.emf.EmfUtil; -import org.eclipse.epsilon.emc.emf.InMemoryEmfModel; -import org.eclipse.epsilon.eol.EolModule; -import org.eclipse.epsilon.eol.exceptions.EolRuntimeException; -import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException; -import org.eclipse.epsilon.eol.models.IModel; -import org.eclipse.epsilon.eol.tools.MathTool; -import org.eclipse.epsilon.eol.types.AbstractToolNativeTypeDelegate; -import org.eclipse.epsilon.eol.types.EolClasspathNativeTypeDelegate; -import org.eclipse.epsilon.etl.EtlModule; -import org.eclipse.epsilon.evl.EvlModule; -import org.eclipse.epsilon.evl.IEvlFixer; -import org.eclipse.epsilon.evl.IEvlModule; -import org.eclipse.epsilon.evl.emf.validation.CompositeEValidator; -import org.eclipse.epsilon.evl.emf.validation.EvlValidator; -import org.eclipse.epsilon.evl.emf.validation.EvlValidator.ValidationProblemListener; -import org.eclipse.epsilon.evl.execute.UnsatisfiedConstraint; -import org.eclipse.epsilon.profiling.Profiler; -import org.eclipse.epsilon.profiling.ProfilerTargetSummary; -import org.eclipse.epsilon.profiling.ProfilingExecutionListener; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.ocl.pivot.utilities.OCL; import org.eclipse.ocl.pivot.utilities.PivotUtil; @@ -88,17 +64,17 @@ public class Validator { private static void registerValidator(EPackage ePackage, EValidator validator) { EValidator existingValidator = EValidator.Registry.INSTANCE.getEValidator(ePackage); - if (existingValidator instanceof CompositeEValidator) { - ((CompositeEValidator) existingValidator).getDelegates().add(validator); - } else { - if (existingValidator == null) { - existingValidator = EObjectValidator.INSTANCE; - } - CompositeEValidator newValidator = new CompositeEValidator(); - newValidator.getDelegates().add(existingValidator); - newValidator.getDelegates().add(validator); - EValidator.Registry.INSTANCE.put(ePackage, newValidator); - } +// if (existingValidator instanceof CompositeEValidator) { +// ((CompositeEValidator) existingValidator).getDelegates().add(validator); +// } else { +// if (existingValidator == null) { +// existingValidator = EObjectValidator.INSTANCE; +// } +// CompositeEValidator newValidator = new CompositeEValidator(); +// newValidator.getDelegates().add(existingValidator); +// newValidator.getDelegates().add(validator); +// EValidator.Registry.INSTANCE.put(ePackage, newValidator); +// } } public void validateOCL2(Resource r) { @@ -154,165 +130,165 @@ public class Validator { } } - public List validate(Resource r) throws Exception { - List violations = new ArrayList<>(); - String prefix = "tdl-generated-ETSI-ES-203-119-"; - String suffix = "-fixed.evl"; - //TODO: Change versions to published? - List constraints = List.of( - prefix+"1-V1.5.1"+suffix, - prefix+"4-V1.4.1"+suffix, - prefix+"7-V1.2.1"+suffix - ); - try { - //TODO: This is very important otherwise all kinds of weird problems might occur (in case it may be put in the handler as well) - EcoreUtil.resolveAll(r); - - //TODO: Run all, maintain generated and fixed for differencing between versions and manual interventions - //FIXED: Meta-models not resolved in plugin mode? -> fixed - IModel tdlModel = getTDLModel(r, true, false); - tdlModel.load(); - List dependencies = new ArrayList<>(); - //TODO: this can cause duplicate definitions, resolveAll above makes this unnecessary -// System.out.println("Loading validation dependencies for: "+r.getURI().path()); -// for (Resource d : r.getResourceSet().getResources()) { -// if (d!=r) { -// System.out.println(" Loading "+d.getURI().path()); -// IModel dModel = getTDLModel(d, true, false); -// dModel.load(); -// dependencies.add(dModel); +// public List validate(Resource r) throws Exception { +// List violations = new ArrayList<>(); +// String prefix = "tdl-generated-ETSI-ES-203-119-"; +// String suffix = "-fixed.evl"; +// //TODO: Change versions to published? +// List constraints = List.of( +// prefix+"1-V1.5.1"+suffix, +// prefix+"4-V1.4.1"+suffix, +// prefix+"7-V1.2.1"+suffix +// ); +// try { +// //TODO: This is very important otherwise all kinds of weird problems might occur (in case it may be put in the handler as well) +// EcoreUtil.resolveAll(r); +// +// //TODO: Run all, maintain generated and fixed for differencing between versions and manual interventions +// //FIXED: Meta-models not resolved in plugin mode? -> fixed +// IModel tdlModel = getTDLModel(r, true, false); +// tdlModel.load(); +// List dependencies = new ArrayList<>(); +// //TODO: this can cause duplicate definitions, resolveAll above makes this unnecessary +//// System.out.println("Loading validation dependencies for: "+r.getURI().path()); +//// for (Resource d : r.getResourceSet().getResources()) { +//// if (d!=r) { +//// System.out.println(" Loading "+d.getURI().path()); +//// IModel dModel = getTDLModel(d, true, false); +//// dModel.load(); +//// dependencies.add(dModel); +//// } +//// } +//// String source = "epsilon/constraints/tdl.evl"; +// +// for (String part : constraints) { +// String source = "epsilon/constraints/"+part; +// URI uri = ResourceHandler.getSourceUri(this.getClass(), "org.etsi.mts.tdl.constraints", source); +// +// EvlModule module = new EvlModule(); +// module.parse(uri); +// +// //DONE: For some reason default classpath delegate does not work -> add custom delegate +//// module.getContext().getNativeTypeDelegates().add(new EolClasspathNativeTypeDelegate()); +// module.getContext().getNativeTypeDelegates().add(new XtextBridgeNativeTypeDelegate()); +// //FIXED: Defer warnings in case necessary -> not at present +//// module.getContext().setWarningStream(new PrintStream("Epsilon.log")); +// +// //TODO: integrate error reporting +// if (module.getParseProblems().size() > 0) { +// System.err.println("Parse errors occured..."); +// for (ParseProblem problem : module.getParseProblems()) { +// System.err.println(problem.toString()); +// } // } +// +//// dumpConstraints(module); +// module.getContext().getModelRepository().addModel(tdlModel); +// +// //add dependencies +// module.getContext().getModelRepository().addModels(dependencies); +// +// //execute +// module.execute(); +// +// EvlModule m = (EvlModule) module; +// violations.addAll(m.getContext().getUnsatisfiedConstraints()); +// +// //filter only within resource +// violations = violations.stream() +// .filter(v -> ((EObject)v.getInstance()).eResource() == r) +// .collect(Collectors.toList()); +// +//// dumpViolations(violations); +// +// //TODO: Needed? New API does not provide it +//// module.reset(); // } -// String source = "epsilon/constraints/tdl.evl"; - - for (String part : constraints) { - String source = "epsilon/constraints/"+part; - URI uri = ResourceHandler.getSourceUri(this.getClass(), "org.etsi.mts.tdl.constraints", source); - - EvlModule module = new EvlModule(); - module.parse(uri); - - //DONE: For some reason default classpath delegate does not work -> add custom delegate -// module.getContext().getNativeTypeDelegates().add(new EolClasspathNativeTypeDelegate()); - module.getContext().getNativeTypeDelegates().add(new XtextBridgeNativeTypeDelegate()); - //FIXED: Defer warnings in case necessary -> not at present -// module.getContext().setWarningStream(new PrintStream("Epsilon.log")); - - //TODO: integrate error reporting - if (module.getParseProblems().size() > 0) { - System.err.println("Parse errors occured..."); - for (ParseProblem problem : module.getParseProblems()) { - System.err.println(problem.toString()); - } - } - -// dumpConstraints(module); - module.getContext().getModelRepository().addModel(tdlModel); - - //add dependencies - module.getContext().getModelRepository().addModels(dependencies); - - //execute - module.execute(); - - EvlModule m = (EvlModule) module; - violations.addAll(m.getContext().getUnsatisfiedConstraints()); - - //filter only within resource - violations = violations.stream() - .filter(v -> ((EObject)v.getInstance()).eResource() == r) - .collect(Collectors.toList()); - -// dumpViolations(violations); - - //TODO: Needed? New API does not provide it -// module.reset(); - } - tdlModel.dispose(); - for (IModel d : dependencies) { - d.dispose(); - } - - } catch (URISyntaxException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (Exception e) { - //TODO: Error message refinements - e.printStackTrace(); - System.err.println(e.getMessage() - .replaceAll("\n.+epsilon/", "\n at (epsilon/") -// .replaceAll("\\.", "") -// .replaceAll("evl@", "evl:") -// .replaceAll(":(\\d+).+", ":$1)") -// .replaceAll("-", "") -// .replaceAll("\n.+/", "\n at (") - ); - throw(e); +// tdlModel.dispose(); +// for (IModel d : dependencies) { +// d.dispose(); +// } +// +// } catch (URISyntaxException e) { +// // TODO Auto-generated catch block // e.printStackTrace(); - } - return violations; - } - - - public void dumpViolations(List violations, boolean includeLocation) { - for (UnsatisfiedConstraint constraint : violations) { - System.out.println(" Validator: " + constraint.getMessage()); - //TODO: this can only work with XtextResources - if (includeLocation && ((EObject) constraint.getInstance()).eResource() instanceof XtextResource) { - ICompositeNode node = NodeModelUtils.findActualNodeFor((EObject) constraint.getInstance()); - String text = "Line "+node.getStartLine()+"-"+node.getEndLine()+ ": "+node.getText().trim(); - System.out.println(" " + text); - } else { - //TODO: handle other resources - } - } - } +// } catch (Exception e) { +// //TODO: Error message refinements +// e.printStackTrace(); +// System.err.println(e.getMessage() +// .replaceAll("\n.+epsilon/", "\n at (epsilon/") +//// .replaceAll("\\.", "") +//// .replaceAll("evl@", "evl:") +//// .replaceAll(":(\\d+).+", ":$1)") +//// .replaceAll("-", "") +//// .replaceAll("\n.+/", "\n at (") +// ); +// throw(e); +//// e.printStackTrace(); +// } +// return violations; +// } - private void dumpConstraints(EvlModule module) { - //Dump -> extract to separate functionality - for (var cx : module.getDeclaredConstraintContexts()) { - System.out.println(cx); - for (var cs : cx.getConstraints()) { - System.out.println(" "+cs); - System.out.println(" check:"+getSnippet(module.getFile(), cs.getCheckBlock().getBody().getRegion())); - System.out.println(" message:"+getSnippet(module.getFile(), cs.getMessageBlock().getBody().getRegion())); - } - } - } - private String getSnippet(File file, Region region) { - String snippet = ""; - try { - List lines = Files.readAllLines(Path.of(file.getPath())); - lines.add(0, ""); - lines = lines.subList(region.getStart().getLine(), region.getEnd().getLine()+1); -// System.out.println(lines); - lines.set(lines.size()-1, lines.get(lines.size()-1).substring(0, region.getEnd().getColumn())); - lines.set(0, lines.get(0).substring(region.getStart().getColumn()-1)); - lines = lines.stream() - .filter(l -> !l.trim().startsWith("//")) - .collect(Collectors.toList()); - snippet = String.join(" ", lines) - .replaceAll("\\s+", " ") - ; - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return snippet; - } - - //TODO: extract to shared library - public IModel getTDLModel(Resource resource, boolean read, boolean write) throws Exception { - EmfModel model; - //FIXED: meta-models not resolved in plugin mode? -> seems to work now -// model = new InMemoryEmfModel(resource); - model = new InMemoryEmfModel("TDL", resource, packages); - model.setStoredOnDisposal(write); - model.setReadOnLoad(read); - model.setCachingEnabled(true); - model.setMetamodelUris(List.of(tdlPackage.eNS_URI, StructuredObjectivesPackage.eNS_URI, ExtendedConfigurationsPackage.eNS_URI)); - return model; - } +// public void dumpViolations(List violations, boolean includeLocation) { +// for (UnsatisfiedConstraint constraint : violations) { +// System.out.println(" Validator: " + constraint.getMessage()); +// //TODO: this can only work with XtextResources +// if (includeLocation && ((EObject) constraint.getInstance()).eResource() instanceof XtextResource) { +// ICompositeNode node = NodeModelUtils.findActualNodeFor((EObject) constraint.getInstance()); +// String text = "Line "+node.getStartLine()+"-"+node.getEndLine()+ ": "+node.getText().trim(); +// System.out.println(" " + text); +// } else { +// //TODO: handle other resources +// } +// } +// } +// +// private void dumpConstraints(EvlModule module) { +// //Dump -> extract to separate functionality +// for (var cx : module.getDeclaredConstraintContexts()) { +// System.out.println(cx); +// for (var cs : cx.getConstraints()) { +// System.out.println(" "+cs); +// System.out.println(" check:"+getSnippet(module.getFile(), cs.getCheckBlock().getBody().getRegion())); +// System.out.println(" message:"+getSnippet(module.getFile(), cs.getMessageBlock().getBody().getRegion())); +// } +// } +// } +// +// private String getSnippet(File file, Region region) { +// String snippet = ""; +// try { +// List lines = Files.readAllLines(Path.of(file.getPath())); +// lines.add(0, ""); +// lines = lines.subList(region.getStart().getLine(), region.getEnd().getLine()+1); +//// System.out.println(lines); +// lines.set(lines.size()-1, lines.get(lines.size()-1).substring(0, region.getEnd().getColumn())); +// lines.set(0, lines.get(0).substring(region.getStart().getColumn()-1)); +// lines = lines.stream() +// .filter(l -> !l.trim().startsWith("//")) +// .collect(Collectors.toList()); +// snippet = String.join(" ", lines) +// .replaceAll("\\s+", " ") +// ; +// } catch (IOException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// return snippet; +// } +// +// //TODO: extract to shared library +// public IModel getTDLModel(Resource resource, boolean read, boolean write) throws Exception { +// EmfModel model; +// //FIXED: meta-models not resolved in plugin mode? -> seems to work now +//// model = new InMemoryEmfModel(resource); +// model = new InMemoryEmfModel("TDL", resource, packages); +// model.setStoredOnDisposal(write); +// model.setReadOnLoad(read); +// model.setCachingEnabled(true); +// model.setMetamodelUris(List.of(tdlPackage.eNS_URI, StructuredObjectivesPackage.eNS_URI, ExtendedConfigurationsPackage.eNS_URI)); +// return model; +// } } diff --git a/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/XtextBridge.java b/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/XtextBridge.java index d870c158159d5b6579bf6d999a2a3dcb9bc59613..2e884828a5dbb66111dbfe6b1974f288e6ac5e4d 100644 --- a/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/XtextBridge.java +++ b/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/XtextBridge.java @@ -1,13 +1,13 @@ package org.etsi.mts.tdl.constraints.evl; import org.eclipse.emf.ecore.EObject; -import org.eclipse.epsilon.eol.tools.AbstractTool; import org.eclipse.xtext.nodemodel.ICompositeNode; import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.eclipse.xtext.resource.XtextResource; //DONE: extract to plugin? -> not for now -public class XtextBridge extends AbstractTool { +public class XtextBridge { +//public class XtextBridge extends AbstractTool { public String getTextFor(EObject o) { String text = ""; if (o.eResource() instanceof XtextResource) { diff --git a/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/XtextBridgeNativeTypeDelegate.java b/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/XtextBridgeNativeTypeDelegate.java index a7e23c2e8a9c2daf0aca396b20d567d1f3d832c3..25a906ab5879a68ab9fe6bdc8f9980b0ea793908 100644 --- a/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/XtextBridgeNativeTypeDelegate.java +++ b/plugins/org.etsi.mts.tdl.constraints/src/org/etsi/mts/tdl/constraints/evl/XtextBridgeNativeTypeDelegate.java @@ -2,16 +2,13 @@ package org.etsi.mts.tdl.constraints.evl; import java.util.List; -import org.eclipse.epsilon.eol.exceptions.EolRuntimeException; -import org.eclipse.epsilon.eol.types.AbstractToolNativeTypeDelegate; - -public class XtextBridgeNativeTypeDelegate extends AbstractToolNativeTypeDelegate{ - +//public class XtextBridgeNativeTypeDelegate extends AbstractToolNativeTypeDelegate{ +public class XtextBridgeNativeTypeDelegate{ public XtextBridgeNativeTypeDelegate() { } - public Object createInstance(String clazz, List parameters) throws EolRuntimeException { + public Object createInstance(String clazz, List parameters) throws Exception { return new XtextBridge() { }; } diff --git a/plugins/org.etsi.mts.tdl.execution.java.codegen/.classpath b/plugins/org.etsi.mts.tdl.execution.java.codegen/.classpath index e801ebfb4680123285c15553dc70584276fe0057..375961e4d6186c871e094278e593739acfe9bf39 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.codegen/.classpath +++ b/plugins/org.etsi.mts.tdl.execution.java.codegen/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.execution.java.codegen/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.execution.java.codegen/.settings/org.eclipse.jdt.core.prefs index c9545f06a4120d5b4a1228fb19f67a1171bc0f5b..23fa13b170502d5a7f7a0549188dbc454a7cf0c8 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.codegen/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.execution.java.codegen/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.execution.java.codegen/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.execution.java.codegen/META-INF/MANIFEST.MF index 5f2f3bd978250d7b41aa2bb122322df1b38a4beb..2a709f987a1c817e26d31f8a3bc265f26d96cbd8 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.codegen/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.execution.java.codegen/META-INF/MANIFEST.MF @@ -4,7 +4,7 @@ Bundle-Name: org.etsi.mts.tdl.execution.java.codegen Bundle-SymbolicName: org.etsi.mts.tdl.execution.java.codegen Bundle-Version: 1.0.0.qualifier Export-Package: org.etsi.mts.tdl.execution.java.codegen -Require-Bundle: org.etsi.mts.tdl.model +Require-Bundle: org.etsi.mts.tdl.model, org.eclipse.xtext Automatic-Module-Name: org.etsi.mts.tdl.execution.java.codegen Bundle-ClassPath: . -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 diff --git a/plugins/org.etsi.mts.tdl.execution.java.codegen/src/org/etsi/mts/tdl/execution/java/codegen/JUnitTestGenerator.java b/plugins/org.etsi.mts.tdl.execution.java.codegen/src/org/etsi/mts/tdl/execution/java/codegen/JUnitTestGenerator.java index 92867b5db012b7e0c7205763520c48c514e9c611..5071fa7836080260686ecdad7f3a096da1dd9363 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.codegen/src/org/etsi/mts/tdl/execution/java/codegen/JUnitTestGenerator.java +++ b/plugins/org.etsi.mts.tdl.execution.java.codegen/src/org/etsi/mts/tdl/execution/java/codegen/JUnitTestGenerator.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Hashtable; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -15,6 +16,11 @@ import java.util.stream.Collectors; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.xtext.nodemodel.ICompositeNode; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.serializer.impl.Serializer; import org.etsi.mts.tdl.Action; import org.etsi.mts.tdl.ActionBehaviour; import org.etsi.mts.tdl.ActionReference; @@ -106,10 +112,10 @@ public class JUnitTestGenerator extends Renderer { public static final String PACKAGE_PREFIX = "org.etsi.mts.tdl.execution.java", CORE_PACKAGE = PACKAGE_PREFIX + ".rt.core", TRI_PACKAGE = PACKAGE_PREFIX + ".tri", - TESTER_CLASS = "TestControl", FUNCTIONS_FIELD = "functions", SYSTEM_ADAPTER_FIELD = "systemAdapter", - VALIDATOR_FIELD = "validator", REPORTER_FIELD = "reporter", HELPER_FIELD = "runtimeHelper"; + TESTER_CLASS = "TestControl", COMPONENT_FIELD = "tc", FUNCTIONS_FIELD = COMPONENT_FIELD + ".functions", SYSTEM_ADAPTER_FIELD = COMPONENT_FIELD + ".systemAdapter", + VALIDATOR_FIELD = COMPONENT_FIELD + ".validator", REPORTER_FIELD = COMPONENT_FIELD + ".reporter", HELPER_FIELD = "runtimeHelper"; - public static final String COMPONENT_CLASS_SUFFIX = "_Component", + public static final String COMPONENT_CLASS_SUFFIX = "_Component", BEHAVIOR_METHOD_PREFIX = "td_", ASSERTION_EXCEPTION = "junit.framework.AssertionFailedError", FUTURE_EXECUTION_EXCEPTION = "java.util.concurrent.ExecutionException", INTERRUPTED_EXCEPTION = "InterruptedException", BREAK_EXCEPTION = "BreakException", @@ -353,7 +359,7 @@ public class JUnitTestGenerator extends Renderer { // XXX Gates - append("protected " + className + "()"); + append("public " + className + "()"); blockOpen(); append("super("); append("new "); @@ -384,10 +390,12 @@ public class JUnitTestGenerator extends Renderer { final List ex = new ArrayList(); List testers = td.getTestConfiguration().getComponentInstance().stream() .filter(c -> c.getRole() == ComponentInstanceRole.TESTER).collect(Collectors.toList()); + Set testerClasses = new HashSet(); testers.forEach(tester -> { String className = getElementName(td); if (testers.size() > 1) className += "_" + getElementName(tester); + testerClasses.add(className); try { this.currentTester = tester; String fClassName = className; @@ -398,11 +406,61 @@ public class JUnitTestGenerator extends Renderer { return; } }); + if (testerClasses.size() > 1) { + String className = getElementName(td); + try { + writeClassFile(packageName, className, + () -> renderTestExecutionClass(fPackageName, className, td, testerClasses)); + } catch (IOException e) { + ex.add(e); + return; + } + } if (!ex.isEmpty()) throw ex.get(0); } + private void renderTestExecutionClass(String packageName, String className, TestDescription td, + Set testerClasses) { + + String tdName = getElementName(td); + + line("package " + packageName + ";"); + newLine(); + + Set imports = new HashSet(); + gatherImports(imports); + writeImports(imports); + + append("public class " + className); + blockOpen(); + newLine(); + + line("@Test"); + append("public void test_" + tdName + "()"); + blockOpen(); + + for (String tClass : testerClasses) + line(tClass + " a" + tClass + " = new " + tClass + "();"); + newLine(); + for (String tClass : testerClasses) + line("a" + tClass + ".configure_" + tdName + "();"); + + newLine(); + line("ComponentExecutor executor = new ComponentExecutor();"); + for (String tClass : testerClasses) + line("executor.addTest(a" + tClass + ".getTestControl(), () -> a" + tClass + ".test_" + tdName + "());"); + + newLine(); + line("executor.execute();"); + + blockClose(); + newLine(); + + blockClose(); + } + private void renderTestDescriptionClass(String packageName, String className, TestDescription td, ComponentInstance tester) { @@ -414,12 +472,22 @@ public class JUnitTestGenerator extends Renderer { gatherImports(td, imports); writeImports(imports); - String componentClassName = classNames.get(tester.getType()); line("@TestInstance(TestInstance.Lifecycle.PER_CLASS)"); - append("public class " + className + " extends " + componentClassName); + append("public class " + className); blockOpen(); newLine(); + + // Component instance + String componentClassName = classNames.get(tester.getType()); + line("private " + componentClassName + " " + COMPONENT_FIELD + ";"); + newLine(); + + append("public " + TESTER_CLASS + " getTestControl()"); + blockOpen(); + line("return " + COMPONENT_FIELD + ";"); + blockClose(); + // Declare TimeLabels td.eAllContents().forEachRemaining(e -> { @@ -430,13 +498,13 @@ public class JUnitTestGenerator extends Renderer { }); newLine(); - writeTestConfiguration(td); + writeTestConfiguration(td, tester); newLine(); writeTypes(td); newLine(); - writeTestDescription(td); + writeTestDescription(td, tester); blockClose(); @@ -471,6 +539,8 @@ public class JUnitTestGenerator extends Renderer { protected void gatherImports(Set imports) { // imports.add("org.junit.*"); imports.add("org.junit.jupiter.api.*"); + imports.add("org.junit.jupiter.params.*"); + imports.add("org.junit.jupiter.params.provider.*"); // imports.add("org.junit.Test"); // imports.add("org.junit.Assert"); @@ -482,18 +552,23 @@ public class JUnitTestGenerator extends Renderer { imports.add(TRI_PACKAGE + ".*"); imports.add(CORE_PACKAGE + ".*"); + imports.add(CORE_PACKAGE + "." + TESTER_CLASS + ".*"); } protected void gatherImports(Element el, Set imports) { this.elementMappings.keySet().forEach(e -> addImport(getMapping(e), imports)); } - private void writeTestConfiguration(TestDescription tc) { + private void writeTestConfiguration(TestDescription tc, ComponentInstance tester) { TestConfiguration config = tc.getTestConfiguration(); line("@BeforeAll"); append("public void configure_" + getElementName(tc) + "()"); blockOpen(); + + // Component instance + String componentClassName = classNames.get(tester.getType()); + line(COMPONENT_FIELD + " = new " + componentClassName + "();"); final List connectionNames = new ArrayList(); config.getConnection().forEach(conn -> { @@ -510,7 +585,7 @@ public class JUnitTestGenerator extends Renderer { callClose(); }); - append("configure(new Connection[] {"); + append(COMPONENT_FIELD + ".configure(new Connection[] {"); boolean first = true; for (String cn : connectionNames) { if (!first) @@ -518,7 +593,9 @@ public class JUnitTestGenerator extends Renderer { first = false; append(cn); } - line("});"); + append("}, "); + writeElement(tester); + line(");"); blockClose(); newLine(); @@ -541,12 +618,12 @@ public class JUnitTestGenerator extends Renderer { } private void writeGetConnection(GateReference tester, GateReference remote) { - append("getConnection(\"" + tester.getComponent().getName() + "\", \"" + tester.getGate().getName() + "\", \"" + append(COMPONENT_FIELD + ".getConnection(\"" + tester.getComponent().getName() + "\", \"" + tester.getGate().getName() + "\", \"" + remote.getComponent().getName() + "\", \"" + remote.getGate().getName() + "\")"); } private void writeGetGateReference(GateReference tester) { - append("getGateReference(\"" + tester.getComponent().getName() + "\", \"" + tester.getGate().getName() + "\")"); + append(COMPONENT_FIELD + ".getGateReference(\"" + tester.getComponent().getName() + "\", \"" + tester.getGate().getName() + "\")"); } private void writeTypes(TestDescription tc) { @@ -610,6 +687,10 @@ public class JUnitTestGenerator extends Renderer { DataType mType = m.getDataType(); declareType(mType, declaredTypes); } + for (org.etsi.mts.tdl.Extension e : ((StructuredDataType) t).getExtension()) { + DataType superType = (DataType) e.getExtending(); + declareType(superType, declaredTypes); + } } else if (t instanceof CollectionDataType) { DataType iType = ((CollectionDataType) t).getItemType(); declareType(iType, declaredTypes); @@ -620,8 +701,19 @@ public class JUnitTestGenerator extends Renderer { if (mapping == null) mapping = getMapping(t, settings.useMapping); String mappingName = name + "_mapping"; - if (mapping != null) + if (mapping != null) { writeMapping(mapping, mappingName, false); + if (t instanceof StructuredDataType) { + for (org.etsi.mts.tdl.Extension e : ((StructuredDataType) t).getExtension()) { + StructuredDataType superType = (StructuredDataType) e.getExtending(); + DataElementMapping superMapping = getMapping(superType); + if (superMapping != null) { + String superMappingName = super.getElementName(superType) + "_mapping"; + line(mappingName + ".setParent(" + superMappingName + ");"); + } + } + } + } line(CORE_PACKAGE + ".TypeImpl " + name + " = new " + CORE_PACKAGE + ".TypeImpl()"); writeSetName(t); @@ -668,7 +760,7 @@ public class JUnitTestGenerator extends Renderer { line(".setIsResource(true)"); writeAddAnnotations(rsMapping); blockCloseParen(); - + for (ParameterMapping pMapping : mapping.getParameterMapping()) { String pName = pMapping.getParameter().getName(); append(".setParameter"); @@ -703,7 +795,7 @@ public class JUnitTestGenerator extends Renderer { append("new ElementImpl(\"" + e.getName() + "\")"); } - private void writeTestDescription(TestDescription tc) { + private void writeTestDescription(TestDescription tc, ComponentInstance tester) { for (TestObjective to : tc.getTestObjective()) { line("/**"); @@ -715,10 +807,21 @@ public class JUnitTestGenerator extends Renderer { } line("@Test"); + + // XXX parameters append("public void test_" + getElementName(tc) + "()"); blockOpen(); + line(BEHAVIOR_METHOD_PREFIX + getElementName(tc) + "(" + COMPONENT_FIELD + ");");; + blockClose(); + newLine(); + + + String componentClassName = classNames.get(tester.getType()); + append("public void " + BEHAVIOR_METHOD_PREFIX + getElementName(tc) + "(" + componentClassName + " " + COMPONENT_FIELD + ")"); + blockOpen(); newLine(); + append("try"); blockOpen(); @@ -744,7 +847,7 @@ public class JUnitTestGenerator extends Renderer { } append("catch (RuntimeException e)"); blockOpen(); - line(REPORTER_FIELD + ".runtimeError(e);"); + line(REPORTER_FIELD + ".runtimeError(" + COMPONENT_FIELD + ".getTesterComponent().getName(), " + "e);"); line("throw e;"); blockClose(); @@ -756,7 +859,11 @@ public class JUnitTestGenerator extends Renderer { public String varName; public String kind; public Behaviour b; - public boolean hasExceptionals = false; + // For alternatives: the block containing remaining behaviours after trigger + public Block altBlock; + public int altTriggerIndex; + // For alternatives: the name of the callables list variable (signals batch mode) + public String altCallablesListName; public FutureInfo(String varName, String kind, Behaviour b) { this.varName = varName; @@ -783,13 +890,12 @@ public class JUnitTestGenerator extends Renderer { List myFutures = new ArrayList(); - boolean writeAfter = true; List exceptionalBehaviours = new ArrayList(); - if (b instanceof AtomicBehaviour) { - - // Atomic behaviours + List periodicThreads = new ArrayList<>(); - // Component check + // Component check: skip atomic behaviours that don't apply to the current + // component. Done before opening the try wrapper so we don't leave it dangling. + if (b instanceof AtomicBehaviour) { if (b instanceof ActionBehaviour) { ComponentInstance c = ((ActionBehaviour) b).getComponentInstance(); if (c != null && !isCurrentComponentInstance(c)) @@ -803,6 +909,109 @@ public class JUnitTestGenerator extends Renderer { if (!isCurrentComponentInstance(v.getComponentInstance())) return; } + } + + // Set up periodic threads and exceptional behaviours BEFORE the try block so the + // variables they declare (Thread, Throwable[], ExceptionalBehaviour) are in scope + // in the finally block below. + if (b instanceof CombinedBehaviour) { + + for (PeriodicBehaviour pb : ((CombinedBehaviour) b).getPeriodic()) { + Optional periodExp = pb.getPeriod().stream() + .filter(le -> isCurrentComponentInstance(le.getComponentInstance())).findFirst(); + if (periodExp.isEmpty()) + continue; + + newLine(); + lineComment(pb.eClass().getName()); + + DataUse periodValue = periodExp.get().getExpression(); + initializeDataUse(periodValue, dataUseVariables); + + String baseName = getElementName(pb); + String threadName = "periodic_" + baseName; + String errorName = "periodicError_" + baseName; + String periodVar = "period_" + baseName; + + // Store period value before thread creation (must be effectively final) + append("long " + periodVar + " = "); + write(periodValue, dataUseVariables); + line(";"); + + line("Throwable[] " + errorName + " = new Throwable[1];"); + append("Thread " + threadName + " = new Thread(() -> "); + blockOpen(); + append("try "); + blockOpen(); + + // Fixed-rate: next execution time tracks start-to-start interval + line("long nextExecution = System.currentTimeMillis() + " + periodVar + ";"); + append("while (!Thread.interrupted()) "); + blockOpen(); + line("long sleepTime = nextExecution - System.currentTimeMillis();"); + line("if (sleepTime > 0) Thread.sleep(sleepTime);"); + + write(pb.getBlock(), null, null, thrownExceptions); + + line("nextExecution += " + periodVar + ";"); + blockClose(); + + blockClose(); + append("catch (" + INTERRUPTED_EXCEPTION + " e) {} "); + append("catch (Throwable e) "); + blockOpen(); + append("synchronized (" + errorName + ") "); + blockOpen(); + line("if (" + errorName + "[0] == null) " + errorName + "[0] = e;"); + blockClose(); + blockClose(); + + blockClose(); + line(");"); + line(threadName + ".start();"); + + periodicThreads.add(new String[]{threadName, errorName}); + } + + // Iterate exceptionals in REVERSE declaration order: TestControl prioritises + // later-added entries, but within a single CombinedBehaviour the FIRST-declared + // exceptional has the highest priority. Adding them in reverse maps declaration + // order to priority correctly. + List exceptionalsList = ((CombinedBehaviour) b).getExceptional(); + for (int ebIdx = exceptionalsList.size() - 1; ebIdx >= 0; ebIdx--) { + ExceptionalBehaviour eb = exceptionalsList.get(ebIdx); + + newLine(); + lineComment(eb.eClass().getName()); + + ComponentInstance gc = eb.getGuardedComponent(); + if (gc != null && !isCurrentComponentInstance(gc)) + continue; + + String exceptionalBehaviourName = getElementName(eb); + append("ExceptionalBehaviour " + exceptionalBehaviourName + " = new ExceptionalBehaviour("); + append(Boolean.toString(eb instanceof InterruptBehaviour)); + line(");"); + + // TODO what to do with those? + Set innerExceptions = new HashSet(); + write(eb.getBlock(), exceptionalBehaviourName, null, innerExceptions); + + line(COMPONENT_FIELD + ".addExceptionalBehaviour(" + exceptionalBehaviourName + ");"); + newLine(); + exceptionalBehaviours.add(exceptionalBehaviourName); + } + } + + // Wrap body emission in try { ... } finally { cleanup } so post-processing + // (periodic thread joins, exceptional removal, completed-notification, objective) + // always runs — even when a child behaviour throws (terminate / break / assertion). + append("try "); + blockOpen(); + + if (b instanceof AtomicBehaviour) { + + // Atomic behaviours // Timing TimeLabel timeLabel = ((AtomicBehaviour) b).getTimeLabel(); @@ -853,6 +1062,8 @@ public class JUnitTestGenerator extends Renderer { a -> a.getKey().getName().equals(LANGUAGE_KEY) && a.getValue().equals(JAVA_LANGUAGE_VALUE))) { append(((InlineAction) b).getBody()); newLine(); + } else { + lineComment("Add annotation @Language: \"Java\" to your inline action"); } } @@ -860,7 +1071,6 @@ public class JUnitTestGenerator extends Renderer { else if (b instanceof Assignment) { VariableUse v = ((Assignment) b).getVariable(); initializeDataUse(((Assignment) b).getExpression(), dataUseVariables); - append("this."); write(v, dataUseVariables); append(" = "); write(((Assignment) b).getExpression(), dataUseVariables); @@ -883,12 +1093,9 @@ public class JUnitTestGenerator extends Renderer { if (verdict != null) write(((Assertion) b).getOtherwise(), dataUseVariables); else - append("Verdict.fail"); + append("VerdictImpl.fail"); line(");"); - writeNotification(b, false); - writeObjective(b); - writeAfter = false; line("throw new " + ASSERTION_EXCEPTION + "(\"" + getMessage(b) + "\");"); blockClose(); @@ -907,20 +1114,16 @@ public class JUnitTestGenerator extends Renderer { throw new RuntimeException("Break not contained in a Block " + getQName(b)); Block bl = (Block) ((Break) b).container(); - writeNotification(b, false); - writeObjective(b); - writeAfter = false; - - line("throw new " + BREAK_EXCEPTION + "(\"" + getElementName(bl) + "\");"); + // Indirect throw via helper so the JLS reachability check accepts any + // generated code that follows (e.g. cleanup or trailing siblings). + line(COMPONENT_FIELD + ".breakBlock(\"" + getElementName(bl) + "\");"); thrownExceptions.add(BREAK_EXCEPTION); } else if (b instanceof Stop) { - writeNotification(b, false); - writeObjective(b); - writeAfter = false; - - line("throw new " + STOP_EXCEPTION + "Impl" + "(\"Stop " + getQName(b) + "\");"); + // Indirect throw via helper so the JLS reachability check accepts any + // generated code that follows (e.g. cleanup or trailing siblings). + line(COMPONENT_FIELD + ".terminate(\"Stop " + getQName(b) + "\");"); thrownExceptions.add(STOP_EXCEPTION); } @@ -928,39 +1131,38 @@ public class JUnitTestGenerator extends Renderer { else if (b instanceof TimerStart) { DataUse period = ((TimerStart) b).getPeriod(); Time timeType = resolveTimeType(period); + DataElementMapping mapping = getMappingChecked(timeType); initializeDataUse(period, dataUseVariables); - append(getTimerName(((TimerOperation) b).getTimer()) + ".start("); + append(COMPONENT_FIELD + "." + getTimerName(((TimerOperation) b).getTimer()) + ".start("); write(period, dataUseVariables); if (timeType != null) - append(", TimeUnit." + timeType.getName()); + append(", TimeUnit." + mapping.getElementURI()); line(");"); } else if (b instanceof TimerStop) { - append(getTimerName(((TimerOperation) b).getTimer()) + ".stop();"); + append(COMPONENT_FIELD + "." + getTimerName(((TimerOperation) b).getTimer()) + ".stop();"); } else if (b instanceof TimeOut) { - FutureInfo futureInfo = writeTesterInput(b, dataUseVariables, true, true); + FutureInfo futureInfo = writeTesterInput(b, dataUseVariables); myFutures.add(futureInfo); } // Gate operations else if (b instanceof Wait) { - FutureInfo futureInfo = declareFuture(b, dataUseVariables, true); - line(futureInfo.varName + ".get();"); + FutureInfo futureInfo = declareFuture(b, dataUseVariables); + line(futureInfo.varName + ".execute().get();"); } else if (b instanceof Quiescence) { - FutureInfo futureInfo = writeTesterInput(b, dataUseVariables, true, true); + FutureInfo futureInfo = writeTesterInput(b, dataUseVariables); myFutures.add(futureInfo); } else if (b instanceof Message) { if (isTesterInput(b)) { - FutureInfo futureInfo = writeTesterInput(b, dataUseVariables, true, true); + FutureInfo futureInfo = writeTesterInput(b, dataUseVariables); myFutures.add(futureInfo); - thrownExceptions.add(INTERRUPTED_EXCEPTION); - thrownExceptions.add(FUTURE_EXECUTION_EXCEPTION); } else { @@ -973,6 +1175,9 @@ public class JUnitTestGenerator extends Renderer { convertToData(arg, dataUseVariables); append(", "); writeGetConnection(m.getSourceGate(), t.getTargetGate()); + append(", "); + writeGetGateReference(m.getSourceGate()); + append(".getComponent()"); line(");"); } @@ -985,7 +1190,7 @@ public class JUnitTestGenerator extends Renderer { boolean isTesterInput = isTesterInput(b); if (isCall) { if (!isTesterInput) { - FutureInfo futureInfo = writeTesterInput(b, dataUseVariables, true, true); + FutureInfo futureInfo = writeTesterInput(b, dataUseVariables); myFutures.add(futureInfo); } else { @@ -997,7 +1202,8 @@ public class JUnitTestGenerator extends Renderer { // Test description call else if (b instanceof TestDescriptionReference) { TestDescription td = ((TestDescriptionReference) b).getTestDescription(); - // XXX + String tdName = getElementName(td); + line("new " + tdName + "()." + BEHAVIOR_METHOD_PREFIX + tdName + "(" + COMPONENT_FIELD + ");");; } @@ -1005,37 +1211,11 @@ public class JUnitTestGenerator extends Renderer { } // Combined behaviours + // (Periodic threads and exceptional behaviours have already been set up + // before the try block above so the variables are visible in finally.) else if (b instanceof CombinedBehaviour) { - for (PeriodicBehaviour pb : ((CombinedBehaviour) b).getPeriodic()) { - // XXX run periodic in parallel with separate completion service - lineComment(pb.eClass().getName() + " not supported currently"); - } - - for (ExceptionalBehaviour eb : ((CombinedBehaviour) b).getExceptional()) { - - newLine(); - lineComment(eb.eClass().getName()); - - ComponentInstance gc = eb.getGuardedComponent(); - if (gc != null && !isCurrentComponentInstance(gc)) - continue; - - String exceptionalBehaviourName = getElementName(eb); - append("ExceptionalBehaviour " + exceptionalBehaviourName + " = new ExceptionalBehaviour("); - append(Boolean.toString(eb instanceof InterruptBehaviour)); - line(");"); - - // TODO what to do with those? - Set innerExceptions = new HashSet(); - write(eb.getBlock(), exceptionalBehaviourName, null, innerExceptions); - - line("addExceptionalBehaviour(" + exceptionalBehaviourName + ");"); - newLine(); - exceptionalBehaviours.add(exceptionalBehaviourName); - } - // Single block if (b instanceof CompoundBehaviour) { write(((CompoundBehaviour) b).getBlock(), null, null, thrownExceptions); @@ -1074,7 +1254,54 @@ public class JUnitTestGenerator extends Renderer { } // Multiple blocks else if (b instanceof AlternativeBehaviour) { - // XXX + + String altsListName = "callables_" + getElementName(b); + line("List " + altsListName + " = new java.util.LinkedList<>();"); + + List blocks = ((AlternativeBehaviour) b).getBlock(); + for (int blockIdx = 0; blockIdx < blocks.size(); blockIdx++) { + Block bl = blocks.get(blockIdx); + + // Find first participating tester-input in this block + Behaviour triggerBehaviour = null; + int triggerIndex = -1; + for (int i = 0; i < bl.getBehaviour().size(); i++) { + Behaviour beh = bl.getBehaviour().get(i); + if (isParticipating(beh)) { + if (!isTesterInput(beh)) + throw new RuntimeException( + "Alternative block should start with tester input: " + getMessage(beh)); + triggerBehaviour = beh; + triggerIndex = i; + break; + } + } + if (triggerBehaviour == null) + continue; + + lineComment("Alternative " + blockIdx); + + // Handle guard + Optional guard = bl.getGuard().stream() + .filter(le -> isCurrentComponentInstance(le.getComponentInstance())).findFirst(); + if (guard.isPresent()) { + DataUse g = guard.get().getExpression(); + initializeDataUse(g, dataUseVariables); + append("if ("); + write(g, dataUseVariables); + append(") "); + } + + // Create callable (without submitting) + FutureInfo callable = writeTesterInput(triggerBehaviour, dataUseVariables); + callable.altBlock = bl; + callable.altTriggerIndex = triggerIndex; + callable.altCallablesListName = altsListName; + line(altsListName + ".add(" + callable.varName + ");"); + newLine(); + + myFutures.add(callable); + } } else if (b instanceof ConditionalBehaviour) { List blocks = ((ConditionalBehaviour) b).getBlock(); @@ -1087,122 +1314,240 @@ public class JUnitTestGenerator extends Renderer { } } else if (b instanceof ParallelBehaviour) { - // XXX run ParallelBehaviour in parallel with separate completion service - lineComment(b.eClass().getName() + " not supported currently"); + List blocks = ((ParallelBehaviour) b).getBlock(); + String baseName = getElementName(b); + String threadsName = "parallelThreads_" + baseName; + String errorName = "parallelError_" + baseName; + + // Thread array and error holder + line("Thread[] " + threadsName + " = new Thread[" + blocks.size() + "];"); + line("Throwable[] " + errorName + " = new Throwable[1];"); + for (int i = 0; i < blocks.size(); i++) { + append(threadsName + "[" + i + "] = new Thread(() -> "); + blockOpen(); + append("try "); + blockOpen(); - } + write(blocks.get(i), null, null, thrownExceptions); - } - if (writeAfter) { - writeNotification(b, false); - writeObjective(b); + blockClose(); + append("catch (Throwable e) "); + blockOpen(); + append("synchronized (" + errorName + ") "); + blockOpen(); + line("if (" + errorName + "[0] == null) " + errorName + "[0] = e;"); + blockClose(); + // Interrupt all sibling threads + line("for (Thread t : " + threadsName + ") if (t != Thread.currentThread()) t.interrupt();"); + blockClose(); + + blockClose(); + line(");"); + } + newLine(); + + // Start all threads + for (int i = 0; i < blocks.size(); i++) + line(threadsName + "[" + i + "].start();"); + newLine(); + + // Join all threads + for (int i = 0; i < blocks.size(); i++) + line(threadsName + "[" + i + "].join();"); + thrownExceptions.add(INTERRUPTED_EXCEPTION); + newLine(); + + // Propagate first error, preserving checked exception types + append("if (" + errorName + "[0] != null) "); + blockOpen(); + line("if (" + errorName + "[0] instanceof " + STOP_EXCEPTION + ") throw (" + STOP_EXCEPTION + ") " + errorName + "[0];"); + line("if (" + errorName + "[0] instanceof " + BREAK_EXCEPTION + ") throw (" + BREAK_EXCEPTION + ") " + errorName + "[0];"); + line("if (" + errorName + "[0] instanceof RuntimeException) throw (RuntimeException) " + errorName + "[0];"); + line("if (" + errorName + "[0] instanceof Error) throw (Error) " + errorName + "[0];"); + line("throw new RuntimeException(" + errorName + "[0]);"); + blockClose(); + thrownExceptions.add(STOP_EXCEPTION); + thrownExceptions.add(BREAK_EXCEPTION); + + } - newLine(); - exceptionalBehaviours.forEach(eb -> { - line("removeExceptionalBehaviour(" + eb + ");"); - }); } if (futures == null) { if (!myFutures.isEmpty()) { - String futureName = getElementName(b) + "_future"; - line("Future " + futureName + " = next();"); + // Determine if this is an alternative (callables list already generated) + // or a single tester-input (need to generate callables list here) + String callablesListName = myFutures.get(0).altCallablesListName; + if (callablesListName == null) { + callablesListName = "callables_" + getElementName(b); + line("List " + callablesListName + " = new java.util.LinkedList<>();"); + for (FutureInfo f : myFutures) + line(callablesListName + ".add(" + f.varName + ");"); + newLine(); + } + + String batchName = "batch_" + getElementName(b); + String futuresName = "futures_" + getElementName(b); + String excName = "exc_" + getElementName(b); + String winnerName = "winner_" + getElementName(b); + String interruptedName = "interrupted_" + getElementName(b); + + // Interrupt loop: re-submit if an interrupt behaviour fires + append("while (true)"); + blockOpen(); + + // Submit alternatives + exceptionals + anyReceivers as a single batch on + // every involved ReceiverHub: the hub does not start matching until every + // expectable has been added, so an exceptional cannot lose its message to + // an alternative simply because of submission ordering. + line("BatchedFutures " + batchName + " = " + COMPONENT_FIELD + + ".executeAlternativesAndExceptionals(" + callablesListName + ");"); + line("List> " + futuresName + " = " + batchName + ".alternatives;"); + line("List> " + excName + " = " + batchName + ".exceptionals;"); + newLine(); + + // Wait for first completion + line("Future " + winnerName + " = " + COMPONENT_FIELD + ".next();"); + line("boolean " + interruptedName + " = false;"); + newLine(); append("try "); blockOpen(); - boolean first = true; - for (FutureInfo f : myFutures) { - if (!first) + // If/else for each future + for (int i = 0; i < myFutures.size(); i++) { + FutureInfo f = myFutures.get(i); + + if (i > 0) append(" else "); - first = false; - append("if (" + f.varName + " == " + futureName + ")"); + append("if (" + futuresName + ".get(" + i + ") == " + winnerName + ")"); blockOpen(); - line(f.kind + " result = (" + f.kind + ")" + f.varName + ".get();"); - if (f.kind.equals("InteractionResult")) { - Target localTarget = ((Interaction) b).getTarget().stream() - .filter(t -> isCurrentComponentInstance(t.getTargetGate().getComponent())).findFirst() - .get(); - if (b instanceof Message) { - for (ValueAssignment va : localTarget.getValueAssignment()) { - lineComment("ValueAssignment"); - Variable var = va.getVariable(); - append(getElementName(var)); - append(" = "); - append("(" + getElementName(var.getDataType()) + ")"); - line("result.data.getValue();"); - } - - } else { - // XXX - } - - } else if (f.kind.equals("TimeoutResult")) { - line("throw new " + STOP_EXCEPTION + "Impl" + "(\"Timeout\");"); - thrownExceptions.add(STOP_EXCEPTION); + // Get result + line(f.kind + " result = (" + f.kind + ") " + futuresName + ".get(" + i + ").get();"); - } else - throw new RuntimeException("Unknown execution result kind: " + f.kind); + // Result handling depends on single tester-input vs alternative + if (f.altBlock != null) { + // Alternative: value assignments from trigger + remaining block behaviours + writeResultHandling(f.b, dataUseVariables); + for (int j = f.altTriggerIndex + 1; j < f.altBlock.getBehaviour().size(); j++) { + write(f.altBlock.getBehaviour().get(j), dataUseVariables, null, thrownExceptions); + newLine(); + } + } else { + // Single tester-input: value assignments + timeout handling + writeResultHandling(f.b, dataUseVariables); + if (f.kind.equals("TimeoutResult")) { + line(COMPONENT_FIELD + ".terminate(\"Timeout\");"); + thrownExceptions.add(STOP_EXCEPTION); + } + } blockClose(); } - line(" else "); + // Exceptional behaviour fallback + append(" else "); blockOpen(); - append("ExceptionalBehaviour exceptionalBehaviour = getExceptionalBehaviour("); - append(futureName); - line(");"); - append("if (exceptionalBehaviour != null)"); + line("ExceptionalBehaviour exceptionalBehaviour = " + COMPONENT_FIELD + + ".getExceptionalBehaviour(" + winnerName + ");"); + append("if (exceptionalBehaviour != null) "); blockOpen(); line("exceptionalBehaviour.behaviour.execute();"); + line(interruptedName + " = exceptionalBehaviour.isInterrupt;"); blockClose(); blockClose(); thrownExceptions.add(STOP_EXCEPTION); + blockClose(); + append("catch (" + FUTURE_EXECUTION_EXCEPTION + " | " + INTERRUPTED_EXCEPTION + " e) "); + blockOpen(); + line("if (e.getCause() instanceof RuntimeException) throw (RuntimeException) e.getCause();"); + line("throw new RuntimeException(e.getCause());"); blockClose(); append("finally "); blockOpen(); - // Cancel futures - myFutures.forEach(f -> { - line("stop(" + f.varName + ");"); - - if (f.hasExceptionals) { - append(f.varName); - line("_exceptionals.forEach(f -> stop(f));"); - } - }); + // Cleanup + line(COMPONENT_FIELD + ".cleanupBatch(" + batchName + ");"); + line(futuresName + ".forEach(f -> " + COMPONENT_FIELD + ".stop(f));"); + line(excName + ".forEach(f -> " + COMPONENT_FIELD + ".stop(f));"); + line(COMPONENT_FIELD + ".resumeReceiving();"); blockClose(); -// MethodCall mc = () -> { -// return null; -// }; + // Exit loop unless interrupt behaviour fired + line("if (!" + interruptedName + ") break;"); + blockClose(); // while newLine(); } } else { futures.addAll(myFutures); - // XXX handle futures in caller (e.g. alt) } + + blockClose(); + append("finally "); + blockOpen(); + + // Stop periodic threads and propagate errors + for (String[] pt : periodicThreads) { + String threadName = pt[0]; + String errorName = pt[1]; + newLine(); + line(threadName + ".interrupt();"); + line(threadName + ".join();"); + thrownExceptions.add(INTERRUPTED_EXCEPTION); + append("if (" + errorName + "[0] != null) "); + blockOpen(); + line("if (" + errorName + "[0] instanceof " + STOP_EXCEPTION + ") throw (" + STOP_EXCEPTION + ") " + errorName + "[0];"); + line("if (" + errorName + "[0] instanceof " + BREAK_EXCEPTION + ") throw (" + BREAK_EXCEPTION + ") " + errorName + "[0];"); + line("if (" + errorName + "[0] instanceof RuntimeException) throw (RuntimeException) " + errorName + "[0];"); + line("if (" + errorName + "[0] instanceof Error) throw (Error) " + errorName + "[0];"); + line("throw new RuntimeException(" + errorName + "[0]);"); + blockClose(); + thrownExceptions.add(STOP_EXCEPTION); + thrownExceptions.add(BREAK_EXCEPTION); + } + + writeNotification(b, false); + writeObjective(b); + + newLine(); + exceptionalBehaviours.forEach(eb -> { + line(COMPONENT_FIELD + ".removeExceptionalBehaviour(" + eb + ");"); + }); + + blockClose(); } - private FutureInfo writeTesterInput(Behaviour b, Map dataUseVariables, boolean autoSubmit, - boolean addExceptionals) { - if (b instanceof TimeOut || b instanceof Quiescence || b instanceof Message || b instanceof ProcedureCall) { - FutureInfo future = declareFuture(b, dataUseVariables, autoSubmit); - if (addExceptionals) { - future.hasExceptionals = true; - append("List> "); - append(future.varName); - append("_exceptionals = "); - line("executeExceptionals();"); + /** + * Writes value assignment code for a tester-input result. + * Assumes a local variable "result" of type InteractionResult is in scope. + */ + private void writeResultHandling(Behaviour trigger, Map dataUseVariables) { + if (trigger instanceof Interaction) { + Optional localTargetOpt = ((Interaction) trigger).getTarget().stream() + .filter(t -> isCurrentComponentInstance(t.getTargetGate().getComponent())).findFirst(); + if (localTargetOpt.isPresent() && trigger instanceof Message) { + for (ValueAssignment va : localTargetOpt.get().getValueAssignment()) { + lineComment("ValueAssignment"); + Variable var = va.getVariable(); + append(COMPONENT_FIELD + "." + getElementName(var)); + append(" = "); + append("(" + getElementName(var.getDataType()) + ")"); + line("result.data.getValue();"); + } } - return future; + } + } + + private FutureInfo writeTesterInput(Behaviour b, Map dataUseVariables) { + if (b instanceof TimeOut || b instanceof Quiescence || b instanceof Message || b instanceof ProcedureCall) { + return declareFuture(b, dataUseVariables); } throw new RuntimeException("Behaviour is not tester-input:" + getMessage(b)); } @@ -1250,15 +1595,17 @@ public class JUnitTestGenerator extends Renderer { // Initiating behaviour lineComment("This gets executed automatically with all interactions"); - FutureInfo callable = writeTesterInput(b, dataUseVariables, false, false); + FutureInfo callable = writeTesterInput(b, dataUseVariables); line(exceptionalBehaviourName + ".setCallable(" + callable.varName + ");"); newLine(); append(exceptionalBehaviourName + ".behaviour = () -> "); blockOpen(); + writeNotification((ExceptionalBehaviour) bl.eContainer(), true); + lineComment("Disable while exceptional behaviour is executed"); - line("removeExceptionalBehaviour(" + exceptionalBehaviourName + ");"); + line(COMPONENT_FIELD + ".disableExceptionalBehaviour(" + exceptionalBehaviourName + ");"); newLine(); append("try"); @@ -1287,7 +1634,9 @@ public class JUnitTestGenerator extends Renderer { blockOpen(); lineComment("Enable the exceptional behaviour again"); - line("addExceptionalBehaviour(" + exceptionalBehaviourName + ");"); + line(COMPONENT_FIELD + ".enableExceptionalBehaviour(" + exceptionalBehaviourName + ");"); + + writeNotification((ExceptionalBehaviour) bl.eContainer(), false); blockClose(); blockCloseMethod(); @@ -1321,7 +1670,7 @@ public class JUnitTestGenerator extends Renderer { private FutureInfo declareFuture(Behaviour b, TimeConstraint tc, Map dataUseVariables) { String futureName = "timeConstraint_" + getElementName(tc) + "_" + getElementName(b); - line("Future " + futureName + " = timeConstraint(() -> "); + line("Future " + futureName + " = " + COMPONENT_FIELD + ".timeConstraint(() -> "); blockOpen(); DataUse exp = tc.getTimeConstraintExpression(); @@ -1339,9 +1688,7 @@ public class JUnitTestGenerator extends Renderer { return new FutureInfo(futureName, "TimeoutResult", b); } - private FutureInfo declareFuture(Behaviour b, Map dataUseVariables, boolean autoSubmit) { - String typeSignature = autoSubmit ? "Future" : "ExecutionCallable"; - + private FutureInfo declareFuture(Behaviour b, Map dataUseVariables) { Target localTarget = null; if (b instanceof Interaction) localTarget = ((Interaction) b).getTarget().stream() @@ -1351,9 +1698,7 @@ public class JUnitTestGenerator extends Renderer { String futureName = "timeout_" + getElementName(b); String timerName = getTimerName(((TimerOperation) b).getTimer()); - append(typeSignature + " timeout_" + getElementName(b) + " = timeout(" + timerName + ")"); - if (autoSubmit) - append(".execute()"); + append("ExecutionCallable timeout_" + getElementName(b) + " = " + COMPONENT_FIELD + ".timeout(" + COMPONENT_FIELD + "." + timerName + ")"); line(";"); return new FutureInfo(futureName, "TimeoutResult", b); @@ -1364,11 +1709,9 @@ public class JUnitTestGenerator extends Renderer { DataUse period = ((TimeOperation) b).getPeriod(); initializeDataUse(period, dataUseVariables); - append(typeSignature + " " + futureName + " = sleep("); + append("ExecutionCallable " + futureName + " = " + COMPONENT_FIELD + ".sleep("); write(period, dataUseVariables); append(")"); - if (autoSubmit) - append(".execute()"); line(";"); return new FutureInfo(futureName, "TimeoutResult", b); @@ -1379,7 +1722,7 @@ public class JUnitTestGenerator extends Renderer { DataUse period = ((TimeOperation) b).getPeriod(); initializeDataUse(period, dataUseVariables); - append(typeSignature + " " + futureName + " = noInput("); + append("ExecutionCallable " + futureName + " = " + COMPONENT_FIELD + ".noInput("); write(period, dataUseVariables); append(", "); GateReference gr = ((Quiescence) b).getGateReference(); @@ -1388,8 +1731,6 @@ public class JUnitTestGenerator extends Renderer { else append("null"); append(")"); - if (autoSubmit) - append(".execute()"); line(";"); return new FutureInfo(futureName, "TimeoutResult", b); @@ -1401,13 +1742,11 @@ public class JUnitTestGenerator extends Renderer { DataUse arg = m.getArgument(); initializeDataUse(arg, dataUseVariables); - append(typeSignature + " " + futureName + " = " + (m.isIsTrigger() ? "trigger" : "receive") + "("); + append("ExecutionCallable " + futureName + " = " + COMPONENT_FIELD + "." + (m.isIsTrigger() ? "trigger" : "receive") + "("); convertToData(arg, dataUseVariables); append(", "); writeGetConnection(localTarget.getTargetGate(), m.getSourceGate()); append(")"); - if (autoSubmit) - append(".execute()"); line(";"); return new FutureInfo(futureName, "InteractionResult", b); @@ -1437,14 +1776,11 @@ public class JUnitTestGenerator extends Renderer { arguments.forEach(arg -> initializeDataUse(arg.getDataUse(), dataUseVariables)); replyArguments.forEach(arg -> initializeDataUse(arg.getDataUse(), dataUseVariables)); - append(typeSignature + " " + futureName + " = call("); + append("ExecutionCallable " + futureName + " = " + COMPONENT_FIELD + ".call("); writeCallArguments(pc, reply[0], true, dataUseVariables); append(", "); writeGetConnection(localTarget.getTargetGate(), pc.getSourceGate()); - line(")"); - if (autoSubmit) - append(".execute()"); - line(";"); + line(");"); return new FutureInfo(futureName, "InteractionResult", b); @@ -1590,7 +1926,11 @@ public class JUnitTestGenerator extends Renderer { else varName += "_"; varName += prefix + "datause_" + (dataUseVariables.size() + 1); - DataType type = d.resolveDataType(); + DataType type = null; + if (e instanceof CastDataUse) + type = d.resolveBaseDataType(); + else + type = d.resolveDataType(); boolean isTime = false; if (type == null && d instanceof PredefinedFunctionCall) { // TODO move this to meta-model? @@ -1677,6 +2017,8 @@ public class JUnitTestGenerator extends Renderer { return; if (d instanceof SpecialValueUse) return; + if (d instanceof VariableUse) + return; for (MemberReference r : d.getReduction()) { DataUse idx = r.getCollectionIndex(); @@ -1774,7 +2116,7 @@ public class JUnitTestGenerator extends Renderer { if (m == null) { DataType t = dataInstance.getDataType(); if (isVerdict(t)) { - append("Verdict." + dataInstance.getName()); + append("VerdictImpl." + dataInstance.getName()); } else throw new RuntimeException("Mapping missing for: " + dataInstance.getQualifiedName()); @@ -1862,7 +2204,7 @@ public class JUnitTestGenerator extends Renderer { append(classQName + "." + functionName); } else if (predefinedFunction != null) { - append("this." + FUNCTIONS_FIELD + "." + getPredefinedFunction(predefinedFunction)); + append(FUNCTIONS_FIELD + "." + getPredefinedFunction(predefinedFunction)); } @@ -1904,16 +2246,6 @@ public class JUnitTestGenerator extends Renderer { lineComment("TODO " + HELPER_FIELD + ".clone(" + getElementName(((VariableUse) d).getVariable()) + ")"); } - if (!arguments.isEmpty()) { - for (ParameterBinding arg : arguments) { - // TODO members of collection type - append(ref); - append("."); - writeMemberAssignment(arg.getParameter(), arg.getDataUse(), dataUseVariables); - line(";"); - } - } - if (memberAssignments != null) { for (MemberAssignment ma : memberAssignments) { // TODO members of collection type @@ -1923,6 +2255,17 @@ public class JUnitTestGenerator extends Renderer { line(";"); } } + if (function == null && predefinedFunction == null) { + if (!arguments.isEmpty()) { + for (ParameterBinding arg : arguments) { + // TODO members of collection type + append(ref); + append("."); + writeMemberAssignment(arg.getParameter(), arg.getDataUse(), dataUseVariables); + line(";"); + } + } + } if (collectionItems != null) { for (DataUse item : collectionItems) { String itemRef = dataUseVariables.get(item); @@ -1993,6 +2336,8 @@ public class JUnitTestGenerator extends Renderer { append("TimeUnit." + getElementName(type) + ".toSeconds(" + dataUseVariables.get(d) + ")"); } else { + if (d instanceof VariableUse) + append(COMPONENT_FIELD + "."); append(dataUseVariables.get(d)); if (isUnmapped()) append(".asData()"); @@ -2030,14 +2375,14 @@ public class JUnitTestGenerator extends Renderer { } private void writeCollectionIdnex(DataType t, DataUse idx, Map dataUseVariables) { - boolean isArray = true; + boolean isArray = false; DataElementMapping m = getMapping(t); if (m != null) { String mappedType = m.getElementURI(); - if (!mappedType.contains("[]")) - isArray = false; + if (mappedType.contains("[]")) + isArray = true; } else { - // Fall back to type array + // Fall back to type List } Stack dataUseVariableRef = new Stack(); @@ -2047,10 +2392,10 @@ public class JUnitTestGenerator extends Renderer { write(idx, dataUseVariables); append("]"); } else { - append("read"); + append(".get"); append("("); write(idx, dataUseVariables); - line(");"); + append(")"); } } @@ -2124,7 +2469,7 @@ public class JUnitTestGenerator extends Renderer { append("/* "); line(c.getBody()); line("*/ "); - line(REPORTER_FIELD + ".comment(\"" + c.getBody() + "\");"); + line(REPORTER_FIELD + ".comment(" + COMPONENT_FIELD + ".getTesterComponent().getName(), " + "\"" + c.getBody() + "\");"); }); } @@ -2132,6 +2477,7 @@ public class JUnitTestGenerator extends Renderer { // TODO multiple URIs b.getTestObjective().forEach(to -> { append(REPORTER_FIELD + ".testObjectiveReached("); + append(COMPONENT_FIELD + ".getTesterComponent().getName(), "); append("\"" + to.getObjectiveURI() + "\", "); append("\"" + to.getDescription() + "\""); line(");"); @@ -2140,12 +2486,27 @@ public class JUnitTestGenerator extends Renderer { private void writeNotification(Behaviour b, boolean started) { if (logEvents) { + String behaviour = ""; + if (settings.logBehaviourTraces && b instanceof AtomicBehaviour && b.eResource() instanceof XtextResource) { + String path = b.eResource().getURI().toPlatformString(false); + ICompositeNode node = NodeModelUtils.getNode(b); + List lines = List.of(node.getText().split("\\n")).stream() + .map(l -> l.trim().replaceAll("\\\"", "\\\\\"")) + .filter(l -> !l.startsWith("//") && !l.isBlank()) + .toList(); + String text = String.join("", lines); + //TODO: alternative representation -> expose as setting? + //behaviour = "\\n " + path + ":"+node.getStartLine() + "\\n " +text; + //TODO: make clickable + behaviour = " | " + path + ":"+node.getStartLine() + " | " +text; + } append(REPORTER_FIELD + "."); append(started ? "behaviourStarted" : "behaviourCompleted"); append("("); + append(COMPONENT_FIELD + ".getTesterComponent().getName(), "); if (started) append("\"" + b.eClass().getName() + "\", "); - append("\"" + getQName(b) + "\""); + append("\"" + getQName(b) + behaviour + "\""); //TODO: move to better position? line(");"); // TODO properties } diff --git a/plugins/org.etsi.mts.tdl.execution.java.codegen/src/org/etsi/mts/tdl/execution/java/codegen/Settings.java b/plugins/org.etsi.mts.tdl.execution.java.codegen/src/org/etsi/mts/tdl/execution/java/codegen/Settings.java index 3a9653eaae8d97099ed81ad2c78dbd7930da2083..acc45f3808ebda50aa1d24055eb7a254f99dfc71 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.codegen/src/org/etsi/mts/tdl/execution/java/codegen/Settings.java +++ b/plugins/org.etsi.mts.tdl.execution.java.codegen/src/org/etsi/mts/tdl/execution/java/codegen/Settings.java @@ -7,7 +7,7 @@ public class Settings { private static final String PREFIX = "JavaRendering."; public static final String OUTPUT_DIR = PREFIX + "OutputDir", PACKAGE = PREFIX + "Package", INJECTOR = PREFIX + "Injector", DATE_FORMAT = PREFIX + "DateFormat", USE_MAPPING = PREFIX + "UseMapping", - UNMAPPED_DATA = PREFIX + "UnmappedData"; + UNMAPPED_DATA = PREFIX + "UnmappedData", LOG_BEHAVIOUR_TRACES = PREFIX + "LogBehaviourTraces"; public String outputPath; public File outputFile; @@ -16,9 +16,10 @@ public class Settings { public String customDateFormat; public String useMapping; public boolean unmappedData; + public boolean logBehaviourTraces; public Settings(String outputPath, File outputFile, String outPackage, String injector, String customDateFormat, - String useMapping, boolean unmappedData) { + String useMapping, boolean unmappedData, boolean logBehaviourTraces) { this.outputPath = outputPath; this.outputFile = outputFile; this.outPackage = outPackage; @@ -26,6 +27,7 @@ public class Settings { this.customDateFormat = customDateFormat; this.useMapping = useMapping; this.unmappedData = unmappedData; + this.logBehaviourTraces = logBehaviourTraces; } } diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/.classpath b/plugins/org.etsi.mts.tdl.execution.java.runtime/.classpath index 29d3daa34f3a289a08eb7c1df5b1f6efe2d199e0..4259a946dde7bac1b32e5c15c5d564aa619807a5 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/.classpath +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.execution.java.runtime/.settings/org.eclipse.jdt.core.prefs index 1db269295eb1b9f6d8e61997dc6a71cee24e400b..374fad0b344b426a5f4bc222cf17a10906c367f8 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,8 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -12,4 +12,4 @@ org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/DefaultAdapter.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/DefaultAdapter.java index 35883391f5aba1444f21a2ef95afc97abfab13cd..38b1f61852596e461e27a710466038bb68efc00a 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/DefaultAdapter.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/DefaultAdapter.java @@ -18,33 +18,33 @@ public class DefaultAdapter implements Validator, Reporter { } @Override - public void comment(String body) { + public void comment(String tester, String body) { // TODO Auto-generated method stub - System.out.println(body); + System.out.println("[" + tester + "] " + body); } @Override - public void testObjectiveReached(String uri, String description) { + public void testObjectiveReached(String tester, String uri, String description) { // TODO Auto-generated method stub - System.out.println("Reached: " + uri + " | " + description); + System.out.println("[" + tester + "] Reached: " + uri + " | " + description); } @Override - public void behaviourStarted(String kind, String id, Object... properties) { + public void behaviourStarted(String tester, String kind, String id, Object... properties) { // TODO Auto-generated method stub - System.out.println("Started: " + kind + " | id = " + id); + System.out.println("[" + tester + "] Started: " + kind + " | id = " + id); } @Override - public void behaviourCompleted(String id) { + public void behaviourCompleted(String tester, String id) { // TODO Auto-generated method stub - System.out.println("Completed: id = " + id); + System.out.println("[" + tester + "] Completed: id = " + id); } @Override - public void runtimeError(Throwable t) { + public void runtimeError(String tester, Throwable t) { // TODO Auto-generated method stub - System.err.println(t); + System.err.println("[" + tester + "] " + t); } @Override diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpRequestData.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpRequestData.java index 986ac3a5d009ebfd3c7b2df0c14e4595d666f8dd..6214e37d238bb6c6025010faa670eefd55373605 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpRequestData.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpRequestData.java @@ -9,4 +9,10 @@ public class HttpRequestData { public List headers = new ArrayList<>(); public List parameters = new ArrayList<>(); public Object body; + + @Override + public String toString() { + // TODO Auto-generated method stub + return this.method + " " + this.uri + " HTTP"; + } } diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpResponseData.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpResponseData.java index 74a9929a99fe52b7d4112c05422cb395529682c4..1fd2bb3caefd3f107f094979e5999e5ea2cc2883 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpResponseData.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpResponseData.java @@ -7,4 +7,9 @@ public class HttpResponseData { public String statusMessage; public List headers; public Object body; + + @Override + public String toString() { + return "HTTP " + this.status + (this.statusMessage != null ? " " + this.statusMessage : ""); + } } diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpSystemAdapter.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpSystemAdapter.java index 05d150df5a7856d31c070978a6b1fd7ce53eed52..87e539a60b61de9c4535ee40516ca90eb1602857 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpSystemAdapter.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpSystemAdapter.java @@ -3,27 +3,38 @@ package org.etsi.mts.tdl.execution.java.adapters.http; import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; +import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.regex.Pattern; import org.etsi.mts.tdl.execution.java.rt.core.PojoData; import org.etsi.mts.tdl.execution.java.tri.Argument; +import org.etsi.mts.tdl.execution.java.tri.ComponentInstanceRole; import org.etsi.mts.tdl.execution.java.tri.Connection; import org.etsi.mts.tdl.execution.java.tri.Data; import org.etsi.mts.tdl.execution.java.tri.ElementAnnotation; +import org.etsi.mts.tdl.execution.java.tri.GateReference; import org.etsi.mts.tdl.execution.java.tri.Mapping; import org.etsi.mts.tdl.execution.java.tri.NamedElement; import org.etsi.mts.tdl.execution.java.tri.Procedure; @@ -39,30 +50,55 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; public class HttpSystemAdapter implements SystemAdapter { protected Validator validator; protected Reporter reporter; - private HttpClient.Builder builder; + private static final String defaultSut = ""; + private static final String defaultGate = ""; + + private HttpClient.Builder clientBuilder; private HttpClient client; private ObjectMapper mapper; - private String baseUri = "https://example.com"; private List defaultHeaders = new ArrayList(); - private Connection[] connections; + private Set endpoints = new HashSet(); + + private String serverBaseUri = "/"; + private Map servers = new Hashtable(); - private Queue> unhandledResponses = new ConcurrentLinkedQueue<>(); + private Queue unhandledInputs = new ConcurrentLinkedQueue<>(); + private Map> unhandledRequests = new Hashtable>(); public HttpSystemAdapter(Validator validator, Reporter reporter) { this.validator = validator; this.reporter = reporter; + this.endpoints.add(new HttpEndpoint("", defaultSut, defaultGate, "https://example.com", "/", 0)); } public void setBaseUri(String baseUri) { - this.baseUri = baseUri; + getEndpoint(null, defaultSut, defaultGate).address = baseUri; + getEndpoint(null, defaultSut, defaultGate).baseUri = ""; + } + + public void setEndpoint(String connectionName, String componentName, String gateName, String address, String baseUri, int serverPort) { + this.endpoints.add(new HttpEndpoint(connectionName, componentName, gateName, address, baseUri, serverPort)); + } + + private HttpEndpoint getEndpoint(String connectionName, String componentName, String gateName) { + if (connectionName == null) + connectionName = ""; + for (HttpEndpoint endpoint : this.endpoints) { + if (endpoint.connectionName.equals(connectionName) && endpoint.componentName.equals(componentName) && endpoint.gateName == gateName) + return endpoint; + } + return null; } /** @@ -78,15 +114,34 @@ public class HttpSystemAdapter implements SystemAdapter { } @Override - public void configure(Connection[] connections) { - if (connections.length > 1) - System.err.println("TODO: multiple connections not supported"); - - // TODO multiple connections - this.connections = connections; + public void configure(Connection[] connections, NamedElement component) { + + for (Connection connection : connections) { + for (GateReference gate : connection.getEndPoints()) { + if (gate.getComponentRole() != ComponentInstanceRole.Tester) + continue; + if (!gate.getComponent().equals(component)) + continue; + HttpEndpoint endpoint = this.getEndpoint(connection.getName(), gate.getComponent().getName(), gate.getGate().getName()); + if (endpoint == null) + continue; + if (this.servers.containsKey(endpoint)) + throw new RuntimeException("Invalid endpoint configuration (duplicates)."); + int serverPort = endpoint.port; + try { + HttpServer server = HttpServer.create(new InetSocketAddress(serverPort), 0); + server.createContext(endpoint.baseUri, request -> this.handleRequest(request, endpoint, connection)); + server.setExecutor(null); + server.start(); + this.servers.put(endpoint, server); + } catch (IOException e) { + throw new RuntimeException("Failed to initialize HTTP server with port " + serverPort, e); + } + } + } - builder = HttpClient.newBuilder(); - client = builder.build(); + clientBuilder = HttpClient.newBuilder(); + client = clientBuilder.build(); mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); @@ -104,21 +159,34 @@ public class HttpSystemAdapter implements SystemAdapter { mapper.registerModule(new JsonNullableModule()); } + + public void stop() { + for (HttpServer server: this.servers.values()) + server.stop(5); + } - private void handleResponse(HttpResponse response, Throwable t) { + private void handleRequest(HttpExchange request, HttpEndpoint target, Connection connection) throws IOException { + synchronized (unhandledInputs) { + unhandledInputs.add(new HttpInput(null, request, target, connection)); + unhandledInputs.notifyAll(); + } + } + + private void handleResponse(HttpResponse response, Throwable t, HttpEndpoint target, + Connection connection) { if (t != null) handleError(t); else { - synchronized (unhandledResponses) { - unhandledResponses.add(response); - unhandledResponses.notifyAll(); + synchronized (unhandledInputs) { + unhandledInputs.add(new HttpInput(response, null, target, connection)); + unhandledInputs.notifyAll(); } } } private void handleError(Throwable t) { t.printStackTrace(); - reporter.runtimeError(t); + reporter.runtimeError(null, t); throw new RuntimeException(t); } @@ -130,65 +198,157 @@ public class HttpSystemAdapter implements SystemAdapter { } } - @Override - public void send(Data message, Connection connection) { - HttpRequestData httpData = getRequestData(message); - - HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(); - applyDefaults(requestBuilder); - - // Parameters - String query = null; - for (HttpRequestParameter p : httpData.parameters) { - if (p.value == null) - continue; - switch (p.location) { - case path: { - httpData.uri = httpData.uri.replaceAll(Pattern.quote("{" + p.name + "}"), p.value); - break; - } - case query: { - String queryParameter = p.name + "=" + URLEncoder.encode(p.value, UTF_8); - if (query == null) - query = queryParameter; - else - query += "&" + queryParameter; - break; - } - case cookie: { - System.err.println("TODO: cookie parameters not handled"); - break; - } - } + private void applyDefaults(Headers responseHeaders) { + responseHeaders.add("Content-Type", "application/json"); + responseHeaders.add("Accept", "application/json"); + for (HttpHeader h : defaultHeaders) { + responseHeaders.add(h.name, h.value); } - URI uri = URI.create(baseUri + httpData.uri); - try { - if (query != null) { - if (uri.getQuery() != null) - query = uri.getQuery() + "&" + query; - uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), - query, uri.getFragment()); + } + + @Override + public void send(Data message, Connection connection, NamedElement source) { + + Object data = null; + if (message.getType() instanceof Type) + data = getMappedObject(message); + else + data = message.getValue(); + + if (!(data instanceof HttpRequestData) && !(data instanceof HttpResponseData)) + throw new RuntimeException("Request/response data in unsupported format"); + + GateReference sourceGate = null; + GateReference target = null; + for (GateReference gate : connection.getEndPoints()) + if (!gate.getComponent().equals(source)) { + target = gate; + } else { + sourceGate = gate; } - } catch (URISyntaxException e) { - handleError(e); - } + HttpEndpoint targetEndpoint = this.getEndpoint(connection.getName(), target.getComponent().getName(), target.getGate().getName()); + if (targetEndpoint == null) + // Assume default + targetEndpoint = this.getEndpoint(null, defaultSut, defaultGate); + boolean isRequest = data instanceof HttpRequestData; try { - requestBuilder.uri(uri); - - // TODO logging - reporter.comment("Outgoing (headers): " + httpData.method.toString() + " | " + uri); - - byte[] body = encodeBody(httpData.body); - requestBuilder.method(httpData.method.toString(), HttpRequest.BodyPublishers.ofByteArray(body)); - - for (HttpHeader header : httpData.headers) - requestBuilder.header(header.name, header.value); - - CompletableFuture> responseFuture = client.sendAsync(requestBuilder.build(), - HttpResponse.BodyHandlers.ofString(UTF_8)); + if (isRequest) { + + String remoteUri = targetEndpoint.address; + if (targetEndpoint.port != 0) + remoteUri += ":" + targetEndpoint.port; + + HttpRequestData httpData = (HttpRequestData) data; + + HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(); + applyDefaults(requestBuilder); + + // Parameters + String query = null; + for (HttpRequestParameter p : httpData.parameters) { + if (p.value == null) + continue; + switch (p.location) { + case path: { + httpData.uri = httpData.uri.replaceAll(Pattern.quote("{" + p.name + "}"), p.value); + break; + } + case query: { + String queryParameter = p.name + "=" + URLEncoder.encode(p.value, UTF_8); + if (query == null) + query = queryParameter; + else + query += "&" + queryParameter; + break; + } + case cookie: { + System.err.println("TODO: cookie parameters not handled"); + break; + } + } + } + URI uri = URI.create(remoteUri + httpData.uri); + try { + if (query != null) { + if (uri.getQuery() != null) + query = uri.getQuery() + "&" + query; + uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), + query, uri.getFragment()); + } + } catch (URISyntaxException e) { + handleError(e); + } + requestBuilder.uri(uri); + + // TODO logging + reporter.comment(source.getName(), "Outgoing (headers): " + httpData.method.toString() + " | " + uri); + + byte[] body = encodeBody(httpData.body); + reporter.comment(source.getName(), "Outgoing (body): " + mapper.writeValueAsString(httpData.body)); + requestBuilder.method(httpData.method.toString(), HttpRequest.BodyPublishers.ofByteArray(body)); + + if (httpData.headers != null) + for (HttpHeader header : httpData.headers) + requestBuilder.header(header.name, header.value); + + CompletableFuture> responseFuture = client.sendAsync(requestBuilder.build(), + HttpResponse.BodyHandlers.ofString(UTF_8)); + + HttpEndpoint sourceEndpoint = this.getEndpoint(connection.getName(), sourceGate.getComponent().getName(), sourceGate.getGate().getName()); + responseFuture + .whenCompleteAsync((response, t) -> this.handleResponse(response, t, sourceEndpoint, connection)); + + } else { + + // Request pending + HttpExchange unhandledExchange = null; + synchronized (this.unhandledRequests) { + if (this.unhandledRequests.containsKey(connection)) { + Queue requests = this.unhandledRequests.get(connection); + unhandledExchange = requests.poll(); + } + } - responseFuture.whenCompleteAsync(this::handleResponse); + if (unhandledExchange == null) + throw new RuntimeException("No pending request to respond to"); + + HttpResponseData httpData = (HttpResponseData) data; + + Headers headers = unhandledExchange.getResponseHeaders(); + this.applyDefaults(headers); + if (httpData.headers != null) + for (HttpHeader header : httpData.headers) + headers.add(header.name, header.value); + + // TODO cookie parameters? + /* + for (HttpRequestParameter p : httpData.parameters) { + if (p.value == null) + continue; + switch (p.location) { + case cookie: { + System.err.println("TODO: cookie parameters not handled"); + break; + } + } + } + */ + + byte[] body = encodeBody(httpData.body); + int length = body.length; + + // TODO logging + reporter.comment(source.getName(), "Outgoing (headers): " + httpData.status + " | length=" + length); + reporter.comment(source.getName(), "Outgoing (body): " + mapper.writeValueAsString(httpData.body)); + + unhandledExchange.sendResponseHeaders(httpData.status, length); + + try (OutputStream os = unhandledExchange.getResponseBody()) { + os.write(body); + os.close(); + } + } } catch (IOException e) { handleError(e); @@ -196,47 +356,135 @@ public class HttpSystemAdapter implements SystemAdapter { } @Override - public Data receive(Data expected, Connection connection) throws InterruptedException, AssertionError { - HttpResponseData expectedHttpData = expected != null ? getResponseData(expected) : null; - - synchronized (unhandledResponses) { - HttpResponse response = unhandledResponses.peek(); - while (response == null) { - unhandledResponses.wait(); - response = unhandledResponses.peek(); - } - - // TODO logging - reporter.comment("Incoming: " + response.statusCode() + " | " + response.body()); + public Data receive(Data expected, Connection connection, NamedElement target) + throws InterruptedException, AssertionError { + + synchronized (unhandledInputs) { + HttpInput input = null; + do { + for (HttpInput i : unhandledInputs) + if (i.connection.equals(connection)) + // If input target is null then we assume default endpoint + if (i.target == null || i.target.componentName.equals(target.getName())) { + input = i; + break; + } + if (input == null) + unhandledInputs.wait(); + } while (input == null); + + if (input.response != null) { + + HttpResponseData expectedHttpData = null; + if (expected != null) + if (expected.getValue() instanceof HttpResponseData) + expectedHttpData = (HttpResponseData) expected.getValue(); + + HttpResponse response = input.response; + + String body = response.body(); + + // TODO logging + reporter.comment(target.getName(), "Incoming: " + response.statusCode() + " | " + body); + + try { + + // This is not provided by HttpResponse + if (expectedHttpData != null) + expectedHttpData.statusMessage = null; + + HttpResponseData receivedHttpData = new HttpResponseData(); + receivedHttpData.status = response.statusCode(); + Map> headers = response.headers().map(); + receivedHttpData.headers = new ArrayList<>(); + for (String header : headers.keySet()) { + receivedHttpData.headers.add(new HttpHeader(header, headers.get(header))); + } - try { + Data received = new PojoData<>(receivedHttpData); + if (expected != null) { + if (expectedHttpData.body != null) { + receivedHttpData.body = decodeBody(body, expectedHttpData.body.getClass()); + } + if (this.validator.matches(expected, received)) { + unhandledInputs.remove(input); + return received; + } + + } else { + receivedHttpData.body = body; + unhandledInputs.remove(input); + return received; + } - HttpResponseData receivedHttpData = new HttpResponseData(); - receivedHttpData.status = response.statusCode(); - Map> headers = response.headers().map(); - receivedHttpData.headers = new ArrayList<>(); - for (String header : headers.keySet()) { - receivedHttpData.headers.add(new HttpHeader(header, headers.get(header))); + } catch (IOException e) { + handleError(e); } - Data received = new PojoData<>(receivedHttpData); - if (expected != null) { - if (expectedHttpData.body != null) { - receivedHttpData.body = decodeBody(response.body(), expectedHttpData.body.getClass()); + } else { + HttpRequestData expectedHttpData = null; + if (expected != null) + if (expected.getValue() instanceof HttpRequestData) + expectedHttpData = (HttpRequestData) expected.getValue(); + + HttpExchange exchange = input.exchange; + + if (input.body == null) + try (InputStream is = exchange.getRequestBody()) { + + // TODO other encodings + Charset cs = StandardCharsets.UTF_8; + input.body = new String(is.readAllBytes(), cs); + + // TODO logging + reporter.comment(target.getName(), "Incoming: " + exchange.getRequestMethod() + " | " + input.body); + + } catch (IOException e) { + handleError(e); + } + + try { + + HttpRequestData receivedHttpData = new HttpRequestData(); + receivedHttpData.uri = exchange.getRequestURI().toString(); + receivedHttpData.method = getHttpMethod(exchange.getRequestMethod()); + + Headers headers = exchange.getRequestHeaders(); + receivedHttpData.headers = new ArrayList<>(); + for (String header : headers.keySet()) { + receivedHttpData.headers.add(new HttpHeader(header, headers.get(header))); } - if (this.validator.matches(expected, received)) { - unhandledResponses.remove(); + + Data received = new PojoData<>(receivedHttpData); + boolean isReceived = false; + if (expected != null) { + if (expectedHttpData.body != null) { + receivedHttpData.body = decodeBody(input.body, expectedHttpData.body.getClass()); + } + if (this.validator.matches(expected, received)) { + isReceived = true; + } + + } else { + receivedHttpData.body = input.body; + isReceived = true; + } + + if (isReceived) { + unhandledInputs.remove(input); + synchronized (unhandledRequests) { + Queue requests = unhandledRequests.get(connection); + if (requests == null) + unhandledRequests.put(connection, requests = new LinkedBlockingQueue()); + requests.add(exchange); + unhandledRequests.notifyAll(); + } return received; } - } else { - receivedHttpData.body = response.body(); - unhandledResponses.remove(); - return received; + } catch (IOException e) { + handleError(e); } - - } catch (IOException e) { - handleError(e); } } @@ -244,7 +492,6 @@ public class HttpSystemAdapter implements SystemAdapter { } protected byte[] encodeBody(Object body) throws IOException { - reporter.comment("Outgoing (body): " + mapper.writeValueAsString(body)); return mapper.writeValueAsBytes(body); } @@ -256,17 +503,19 @@ public class HttpSystemAdapter implements SystemAdapter { @Override public Data call(Procedure operation, Argument[] arguments, Data expectedReturn, Data expectedException, - Connection connection) { + Connection connection, NamedElement source) { throw new UnsupportedOperationException("Procedure-based communication is not supported by this adapter."); } @Override - public Data[] receiveCall(Procedure operation, Data[] expectedArguments, Connection connection) { + public Data[] receiveCall(Procedure operation, Data[] expectedArguments, Connection connection, + NamedElement target) { throw new UnsupportedOperationException("Procedure-based communication is not supported by this adapter."); } @Override - public void replyCall(Procedure operation, Data returnValue, Data exception, Connection connection) { + public void replyCall(Procedure operation, Data returnValue, Data exception, Connection connection, + NamedElement source) { throw new UnsupportedOperationException("Procedure-based communication is not supported by this adapter."); } @@ -340,10 +589,47 @@ public class HttpSystemAdapter implements SystemAdapter { return obj; } - protected HttpResponseData getResponseData(Data message) { - if (message.getValue() instanceof HttpResponseData) - return (HttpResponseData) message.getValue(); -// XXX + private HttpMethod getHttpMethod(String method) { + for (HttpMethod m : HttpMethod.values()) + if (m.toString().equalsIgnoreCase(method)) + return m; return null; } + + class HttpInput { + HttpResponse response; + HttpExchange exchange; + HttpEndpoint target; + Connection connection; + + String body; + + public HttpInput(HttpResponse response, HttpExchange exchange, HttpEndpoint target, + Connection connection) { + this.response = response; + this.exchange = exchange; + this.target = target; + this.connection = connection; + } + + } + + class HttpEndpoint { + String connectionName; + String componentName; + String gateName; + String address; + String baseUri; + int port; + + public HttpEndpoint(String connectionName, String componentName, String gateName, String address, String baseUri, int port) { + super(); + this.connectionName = connectionName; + this.componentName = componentName; + this.gateName = gateName; + this.address = address; + this.baseUri = baseUri; + this.port = port; + } + } } \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ComponentExecutor.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ComponentExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..44bb859d2ef3afc14eefb48179445f2590021675 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ComponentExecutor.java @@ -0,0 +1,74 @@ +package org.etsi.mts.tdl.execution.java.rt.core; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ComponentExecutor { + private Set tests = new HashSet(); + + public void addTest(TestControl control, Runnable test) { + synchronized (this.tests) { + this.tests.add(new TestComponentTest(control, test)); + } + } + + public void execute() { + + int count = tests.size(); + + ExecutorService pool = Executors.newFixedThreadPool(count); + CountDownLatch latch = new CountDownLatch(count); + + Set errors = new HashSet<>(); + synchronized (tests) { + for (TestComponentTest test : tests) { + pool.submit(() -> { + try { + test.thread = Thread.currentThread(); + test.test.run(); + + } catch (Throwable t) { + System.err.println(t); + errors.add(new RuntimeException(t)); + + synchronized (tests) { + for (TestComponentTest otherTest : tests) { + if (otherTest == test) + continue; + if (otherTest.thread != null) + otherTest.thread.interrupt(); + } + } + + } finally { + latch.countDown(); + } + }); + } + } + + try { + latch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + pool.shutdown(); + + if (!errors.isEmpty()) + throw errors.iterator().next(); + } + + class TestComponentTest { + TestControl control; + Runnable test; + Thread thread; + + public TestComponentTest(TestControl control, Runnable test) { + this.control = control; + this.test = test; + } + } +} diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ElementImpl.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ElementImpl.java index b1f54b2b378bf3d9eab215bc079a41f8eef94b57..fc9a06488546bbccb63a5a058121cb18f75688e0 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ElementImpl.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ElementImpl.java @@ -39,4 +39,18 @@ public class ElementImpl implements Element { this.getAnnotations().add(new ElementAnnotationImpl(key, value)); return this; } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ElementImpl && name != null) + return name.equals(((ElementImpl)obj).name); + return super.equals(obj); + } + + @Override + public int hashCode() { + if (name != null) + return name.hashCode(); + return super.hashCode(); + } } diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ExceptionalBehaviour.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ExceptionalBehaviour.java index 0af396649c90fbf0e0bc60da135a3a928e479f7d..b9e9ea42be94c04ff0147775adbda20213242907 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ExceptionalBehaviour.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ExceptionalBehaviour.java @@ -23,6 +23,14 @@ public class ExceptionalBehaviour { * Whether the behaviour is an interrupt or default as specified by TDL. */ public boolean isInterrupt; + + /** + * Whether the behaviour is currently active. Disabled exceptional behaviours + * remain in the test control's list (so their position / priority is preserved) + * but are skipped by the matching logic. Used to suppress re-entry while the + * exceptional's own handler is running. + */ + public boolean enabled = true; /** *

The futures for the triggering behaviour (callable). Several futures may exist diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/GateReferenceImpl.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/GateReferenceImpl.java index db1dbcce418d692acaa69ded20f0d19454fd0e17..8914f5570aa46eb9db4261501f62831086f6f042 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/GateReferenceImpl.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/GateReferenceImpl.java @@ -22,11 +22,11 @@ public class GateReferenceImpl implements GateReference { private Element gate; private NamedElement gateType; private GateTypeKind gateTypeKind; - private Element component; + private NamedElement component; private NamedElement componentType; private ComponentInstanceRole role; - public GateReferenceImpl(Element gate, NamedElement gateType, GateTypeKind gateTypeKind, Element component, NamedElement componentType, + public GateReferenceImpl(Element gate, NamedElement gateType, GateTypeKind gateTypeKind, NamedElement component, NamedElement componentType, ComponentInstanceRole role) { this.gate = gate; this.gateType = gateType; @@ -52,7 +52,7 @@ public class GateReferenceImpl implements GateReference { } @Override - public Element getComponent() { + public NamedElement getComponent() { return component; } diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/MappingImpl.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/MappingImpl.java index 160c71e5ca54a0e5bdcc5295417335ee9bb4a9b9..cfa774493c65b985d38e9cee89d928490da60c5e 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/MappingImpl.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/MappingImpl.java @@ -13,6 +13,7 @@ public class MappingImpl extends ElementImpl implements Mapping, TriImpl parameters = new Hashtable(); public MappingImpl() { @@ -23,6 +24,11 @@ public class MappingImpl extends ElementImpl implements Mapping, TriImpl d0, Data d1) { - return d0.equals(d1); + Object v0 = d0.getValue(); + Object v1 = d1.getValue(); + if (v0 == null) + return v1 == null; + return v0.equals(v1); } @Override diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ReceiverHub.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ReceiverHub.java index a68bf089116108ff2ec45a37e02c0509be2d43ae..89d68c88ca52d925857f4b77534e146fd7da9a60 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ReceiverHub.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ReceiverHub.java @@ -2,12 +2,16 @@ package org.etsi.mts.tdl.execution.java.rt.core; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import org.etsi.mts.tdl.execution.java.tri.Argument; import org.etsi.mts.tdl.execution.java.tri.Connection; import org.etsi.mts.tdl.execution.java.tri.Data; -import org.etsi.mts.tdl.execution.java.tri.StopException; +import org.etsi.mts.tdl.execution.java.tri.NamedElement; import org.etsi.mts.tdl.execution.java.tri.SystemAdapter; public class ReceiverHub { @@ -17,13 +21,22 @@ public class ReceiverHub { private SystemAdapter systemAdapter; private Connection connection; + private NamedElement testerComponent; private List expecting = Collections.synchronizedList(new ArrayList<>()); private ExceptionalBehaviour anyReceiver; - public ReceiverHub(SystemAdapter systemAdapter, Connection connection) { + // Per-thread batch state: each thread's entry is {batchSize, batchCount}. + // Expectations from threads with incomplete batches are skipped by run(). + private Map batches = new HashMap<>(); + // Per-thread suspended state: threads whose expectations matched are + // suspended until they finish cleanup and call resume(). + private Set suspendedThreads = new HashSet<>(); + + public ReceiverHub(SystemAdapter systemAdapter, Connection connection, NamedElement testerComponent) { this.systemAdapter = systemAdapter; this.connection = connection; + this.testerComponent = testerComponent; this.thread = new Thread(() -> run(), "Receive from SystemAdapter on " + connection.getName()); this.thread.setDaemon(true); @@ -38,36 +51,69 @@ public class ReceiverHub { this.anyReceiver = anyReceiver; } + public void enableBatch(int size) { + synchronized (expecting) { + batches.put(Thread.currentThread(), new int[]{size, 0}); + } + } + + public void disableBatch() { + synchronized (expecting) { + batches.remove(Thread.currentThread()); + expecting.notifyAll(); + } + } + + public void resume() { + synchronized (expecting) { + suspendedThreads.remove(Thread.currentThread()); + expecting.notifyAll(); + } + } + private synchronized void run() { - int currentlyExpectingIndex = 0; + // Track tried expectables by identity rather than positional index, + // since the expecting list is mutated concurrently by other threads. + // Stale entries after resume are harmless — each hub.receive() call + // creates a new Expectable instance with distinct identity, so stale + // entries from previous cycles never match newly added expectables. + Set tried = new HashSet<>(); while (!stopped) { Expectable currentlyExpecting = null; synchronized (expecting) { - while (expecting.size() <= currentlyExpectingIndex) - try { - expecting.wait(); - } catch (InterruptedException e) { - return; - } - currentlyExpecting = expecting.get(currentlyExpectingIndex); - currentlyExpectingIndex++; + currentlyExpecting = null; + while (currentlyExpecting == null) { + for (Expectable e : expecting) + if (!tried.contains(e) + && !suspendedThreads.contains(e.ownerThread) + && !hasPendingBatch(e.ownerThread)) { + currentlyExpecting = e; + break; + } + if (currentlyExpecting == null) + try { + expecting.wait(); + } catch (InterruptedException e) { + return; + } + } } try { - Data data = systemAdapter.receive(currentlyExpecting.expected, connection); + Data data = systemAdapter.receive(currentlyExpecting.expected, connection, testerComponent); if (data != null) { - currentlyExpectingIndex = 0; + tried.clear(); if (currentlyExpecting.anyReceiver) { // Switch to the first one for reporting synchronized (expecting) { for (Expectable e: expecting) if (!e.ignoreUnmatched) { - currentlyExpecting = expecting.get(0); + currentlyExpecting = e; break; } } } - // XXX this is not correct - expecting.clear(); + expecting.remove(currentlyExpecting); + suspendedThreads.add(currentlyExpecting.ownerThread); synchronized (currentlyExpecting) { currentlyExpecting.received = data; currentlyExpecting.notifyAll(); @@ -76,8 +122,16 @@ public class ReceiverHub { } catch (InterruptedException e) { } catch (AssertionError e) { + tried.add(currentlyExpecting); if (!currentlyExpecting.ignoreUnmatched) currentlyExpecting.error = e; + } catch (RuntimeException e) { + currentlyExpecting.error = e; + expecting.remove(currentlyExpecting); + suspendedThreads.add(currentlyExpecting.ownerThread); + synchronized (currentlyExpecting) { + currentlyExpecting.notifyAll(); + } } } } @@ -91,7 +145,16 @@ public class ReceiverHub { Expectable expectable = new Expectable(expected, ignoreUntil); synchronized (expecting) { expecting.add(expectable); - expecting.notifyAll(); + int[] batch = batches.get(Thread.currentThread()); + if (batch != null) { + batch[1]++; + if (batch[1] >= batch[0]) { + batches.remove(Thread.currentThread()); + expecting.notifyAll(); + } + } else { + expecting.notifyAll(); + } } try { synchronized (expectable) { @@ -100,8 +163,12 @@ public class ReceiverHub { } catch (InterruptedException e) { return null; } + if (expectable.error instanceof AssertionError) + throw (AssertionError) expectable.error; + if (expectable.error instanceof RuntimeException) + throw (RuntimeException) expectable.error; if (expectable.error != null) - throw expectable.error; + throw new RuntimeException(expectable.error); return expectable.received; } } finally { @@ -114,12 +181,18 @@ public class ReceiverHub { return null; } + /** Must be called while holding the expecting lock. */ + private boolean hasPendingBatch(Thread thread) { + return batches.containsKey(thread); + } + class Expectable { Data expected; Data received; - AssertionError error; + Throwable error; boolean ignoreUnmatched = false; boolean anyReceiver = false; + Thread ownerThread = Thread.currentThread(); public Expectable(Data expected, boolean ignoreUnmatched) { this.expected = expected; diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/TestControl.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/TestControl.java index cc13d75c7636297f638a4ecf7d275625280c9ec8..771cd0292fbc92fc3e13122d1cd057b3f42495a7 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/TestControl.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/TestControl.java @@ -1,9 +1,11 @@ package org.etsi.mts.tdl.execution.java.rt.core; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Hashtable; import java.util.List; +import java.util.HashMap; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; @@ -14,11 +16,15 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.etsi.mts.tdl.execution.java.tri.Argument; +import org.etsi.mts.tdl.execution.java.tri.ComponentInstanceRole; import org.etsi.mts.tdl.execution.java.tri.Connection; import org.etsi.mts.tdl.execution.java.tri.Data; +import org.etsi.mts.tdl.execution.java.tri.Element; import org.etsi.mts.tdl.execution.java.tri.GateReference; +import org.etsi.mts.tdl.execution.java.tri.NamedElement; import org.etsi.mts.tdl.execution.java.tri.PredefinedFunctions; import org.etsi.mts.tdl.execution.java.tri.Reporter; +import org.etsi.mts.tdl.execution.java.tri.StopException; import org.etsi.mts.tdl.execution.java.tri.SystemAdapter; import org.etsi.mts.tdl.execution.java.tri.Validator; @@ -34,16 +40,26 @@ public class TestControl { public PredefinedFunctions functions; private Connection[] connections; + private NamedElement testerComponent; private Map receiverHubs = Collections .synchronizedMap(new Hashtable()); - protected ExecutorCompletionService completionService; + protected ThreadLocal> completionService; protected ExecutorService executor; private final long timeConstraintFrequency = 100; - private List exceptionalBehaviours = Collections - .synchronizedList(new ArrayList()); + private InheritableThreadLocal> exceptionalBehaviours = + new InheritableThreadLocal>() { + @Override + protected List initialValue() { + return Collections.synchronizedList(new ArrayList<>()); + } + @Override + protected List childValue(List parentValue) { + return Collections.synchronizedList(new ArrayList<>(parentValue)); + } + }; protected Map types = new Hashtable(); @@ -58,7 +74,7 @@ public class TestControl { this.functions = injector.getInstance(PredefinedFunctions.class); this.executor = Executors.newCachedThreadPool(); - this.completionService = new ExecutorCompletionService(executor); + this.completionService = ThreadLocal.withInitial(() -> new ExecutorCompletionService<>(executor)); } protected A getInstance(Class clazz) { @@ -72,16 +88,35 @@ public class TestControl { return hub; } - public void configure(Connection[] connections) { - this.systemAdapter.configure(connections); + public void configure(Connection[] connections, NamedElement testerComponent) { + this.systemAdapter.configure(connections, testerComponent); this.connections = connections; + this.testerComponent = testerComponent; this.receiverHubs.values().forEach(r -> r.stop()); this.receiverHubs.clear(); for (Connection c : connections) { - ReceiverHub hub = new ReceiverHub(this.systemAdapter, c); + boolean isMyTester = false; + for (GateReference gr: c.getEndPoints()) { + if (gr.getComponentRole() != ComponentInstanceRole.Tester) + continue; + if (this.testerComponent.equals(gr.getComponent())) { + isMyTester = true; + break; + } + } + if (!isMyTester) + continue; + + ReceiverHub hub = new ReceiverHub(this.systemAdapter, c, testerComponent); receiverHubs.put(c, hub); + // TODO: anyReceiver is currently only active during tester-input processing + // (submitted as part of executeAlternativesAndExceptionals). Consider making + // it always active to catch unexpected messages between tester-input steps. + // Check if TDL spec mandates this. Would require a dedicated thread that + // permanently blocks on hub.receive(null, false) and propagates failures to + // the main test thread. ExceptionalBehaviour anyReceiver = new ExceptionalBehaviour(false); anyReceiver.behaviour = () -> { throw new StopExceptionImpl("Unexpected message received"); @@ -89,8 +124,17 @@ public class TestControl { anyReceiver.callable = new ExecutionCallable() { @Override public ExecutionResult call() throws Exception { - Data data = hub.receive(null, false); - return data != null ? new InteractionResult(data) : null; + try { + Data data = hub.receive(null, false); + return data != null ? new InteractionResult(data) : null; + } catch (RuntimeException e) { + // Propagate SA errors through the behaviour execution path: + // complete the future normally so that the test code can handle + // it as an exceptional behaviour, but replace the behaviour + // to rethrow the real exception. + anyReceiver.behaviour = () -> { throw e; }; + return null; + } } }; @@ -99,6 +143,10 @@ public class TestControl { declareTypes(); } + + public NamedElement getTesterComponent() { + return testerComponent; + } public Connection getConnection(String testerComponentName, String testerGateName, String remoteComponentName, String remoteGateName) { @@ -154,7 +202,7 @@ public class TestControl { public abstract class ExecutionCallable implements Callable { public Future execute() { - return completionService.submit(this); + return completionService.get().submit(this); } } @@ -166,11 +214,122 @@ public class TestControl { } } - public List> executeExceptionals() { - List> futures = new ArrayList<>(); - exceptionalBehaviours.forEach(exc -> futures.add(exc.execute())); - receiverHubs.values().forEach(hub -> futures.add(hub.getAnyReceiver().execute())); - return futures; + public abstract class InteractionCallable extends ExecutionCallableWithDefaults { + public abstract ReceiverHub getReceiver(); + } + + /** + * Result of {@link #executeAlternativesAndExceptionals(List)}: separate future + * lists for the alternative and exceptional callables, both submitted under a + * single batched receive on every involved {@link ReceiverHub}. The set of + * touched hubs is also captured so {@link #cleanupBatch(BatchedFutures)} can + * disable batch mode on exactly those hubs and nothing else. + */ + public static class BatchedFutures { + public final List> alternatives; + public final List> exceptionals; + public final Collection batchedHubs; + + public BatchedFutures(List> alternatives, + List> exceptionals, + Collection batchedHubs) { + this.alternatives = alternatives; + this.exceptionals = exceptionals; + this.batchedHubs = batchedHubs; + } + } + + /** + * Submit alternative callables together with all currently enabled exceptional + * behaviour callables (and per-hub anyReceivers) as a single batch on every + * affected {@link ReceiverHub}, so the hub does not start matching until every + * expectable from this round has been added. Without this, the hub could match + * an alternative against a message that an exceptional was meant to consume. + * + *

Exceptional callables are submitted in reverse list order so that the + * later-added entries (inner CombinedBehaviours, and within a CombinedBehaviour + * the first-declared exceptional) end up at the front of the hub's expecting + * list and therefore win matches first. + */ + public BatchedFutures executeAlternativesAndExceptionals(List alternatives) { + // Snapshot enabled exceptionals in priority order (reverse list order) + List enabledExcs = new ArrayList<>(); + List excs = exceptionalBehaviours.get(); + synchronized (excs) { + for (int i = excs.size() - 1; i >= 0; i--) { + ExceptionalBehaviour exc = excs.get(i); + if (exc.enabled) + enabledExcs.add(exc); + } + } + + // Count expectables per hub: alternatives + exceptional callables + anyReceivers + Map hubCounts = new HashMap<>(); + for (ExecutionCallable c : alternatives) { + if (c instanceof InteractionCallable) { + hubCounts.merge(((InteractionCallable) c).getReceiver(), 1, Integer::sum); + } + } + for (ExceptionalBehaviour exc : enabledExcs) { + if (exc.callable instanceof InteractionCallable) { + hubCounts.merge(((InteractionCallable) exc.callable).getReceiver(), 1, Integer::sum); + } + } + // One anyReceiver per hub + for (ReceiverHub hub : receiverHubs.values()) { + hubCounts.merge(hub, 1, Integer::sum); + } + + // Enable batches BEFORE submitting any callables + hubCounts.forEach((hub, count) -> hub.enableBatch(count)); + + // Submit alternatives + List> altFutures = new ArrayList<>(); + for (ExecutionCallable c : alternatives) { + altFutures.add(c.execute()); + } + + // Submit exceptionals (priority-ordered) and per-hub anyReceivers + List> excFutures = new ArrayList<>(); + for (ExceptionalBehaviour exc : enabledExcs) { + excFutures.add(exc.execute()); + } + receiverHubs.values().forEach(hub -> excFutures.add(hub.getAnyReceiver().execute())); + + return new BatchedFutures(altFutures, excFutures, hubCounts.keySet()); + } + + /** + * Disable batch mode on the hubs that were enabled by the corresponding + * {@link #executeAlternativesAndExceptionals(List)} call. Avoids unnecessary + * {@code notifyAll} on hubs that were never batched. + */ + public void cleanupBatch(BatchedFutures batch) { + batch.batchedHubs.forEach(ReceiverHub::disableBatch); + } + + public void resumeReceiving() { + receiverHubs.values().forEach(hub -> hub.resume()); + } + + /** + * Throws a {@link StopException} to terminate the test execution. Wrapping + * the throw in a method call lets the Java compiler treat the call site as + * potentially completing normally — generated code can therefore have + * statements after a TDL {@code terminate} (or after timeout handling) + * without tripping the unreachable-code check. + */ + public void terminate(String message) throws StopException { + throw new StopExceptionImpl(message); + } + + /** + * Throws a {@link BreakException} for the named block. Same rationale as + * {@link #terminate(String)}: the call form keeps the compiler happy with + * subsequent generated statements. + */ + public void breakBlock(String blockName) throws BreakException { + throw new BreakException(blockName); } public ExecutionCallable timeConstraint(Constraint constraint) { @@ -236,10 +395,14 @@ public class TestControl { } public ExecutionCallable receive(Data expected, Connection connection, boolean isTrigger) { - ExecutionCallableWithDefaults c = new ExecutionCallableWithDefaults() { + InteractionCallable c = new InteractionCallable() { + @Override + public ReceiverHub getReceiver() { + return TestControl.this.getReceiver(connection); + } @Override public ExecutionResult call() throws Exception { - Data data = getReceiver(connection).receive(expected, isTrigger); + Data data = getReceiver().receive(expected, isTrigger); return data != null ? new InteractionResult(data) : null; } }; @@ -278,26 +441,60 @@ public class TestControl { return c; } + /** + * Inner exceptional behaviours and ones declared earlier within the same + * CombinedBehaviour must have precedence. The matching logic favours later + * entries in the list, so callers add outer-first / inner-last and reverse the + * declaration order within a single CombinedBehaviour. + */ public void addExceptionalBehaviour(ExceptionalBehaviour b) { - // TODO Inner exceptional behaviours have precedence - synchronized (exceptionalBehaviours) { - if (!this.exceptionalBehaviours.contains(b)) - this.exceptionalBehaviours.add(b); + + List excs = exceptionalBehaviours.get(); + synchronized (excs) { + if (!excs.contains(b)) + excs.add(b); } } public void removeExceptionalBehaviour(ExceptionalBehaviour b) { - this.exceptionalBehaviours.remove(b); + exceptionalBehaviours.get().remove(b); + b.purgeFutures().forEach(f -> stop(f)); + } + + /** + * Temporarily deactivate an exceptional behaviour without removing it from the + * list. Used while the exceptional's own handler is running, so it does not + * re-fire on itself, while preserving its priority position for when it is + * re-enabled. + */ + public void disableExceptionalBehaviour(ExceptionalBehaviour b) { + b.enabled = false; b.purgeFutures().forEach(f -> stop(f)); } + /** + * Re-activate a previously disabled exceptional behaviour. Position in the + * exceptional behaviour list (and therefore priority) is preserved. + */ + public void enableExceptionalBehaviour(ExceptionalBehaviour b) { + b.enabled = true; + } + public ExceptionalBehaviour getExceptionalBehaviour(Future future) { - synchronized (this.exceptionalBehaviours) { - for (ExceptionalBehaviour b : this.exceptionalBehaviours) { + List excs = exceptionalBehaviours.get(); + synchronized (excs) { + for (ExceptionalBehaviour b : excs) { if (b.isFuture(future)) return b; } } + // Also check hub anyReceivers — these are implicit exceptional behaviours + // for TDL's default verdict logic, not part of the user-defined list. + for (ReceiverHub hub : this.receiverHubs.values()) { + ExceptionalBehaviour anyReceiver = hub.getAnyReceiver(); + if (anyReceiver != null && anyReceiver.isFuture(future)) + return anyReceiver; + } return null; } @@ -305,7 +502,7 @@ public class TestControl { try { Future future; do { - future = this.completionService.take(); + future = this.completionService.get().take(); } while (future.isCancelled()); return future; } catch (InterruptedException e) { @@ -335,13 +532,13 @@ public class TestControl { } }; - Future f1 = this.completionService.submit(c1); - Future f2 = this.completionService.submit(c2); + Future f1 = this.completionService.get().submit(c1); + Future f2 = this.completionService.get().submit(c2); try { Future f; try { - f = this.completionService.take(); + f = this.completionService.get().take(); } catch (InterruptedException e) { // TODO wait was interrupted e.printStackTrace(); diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/GateReference.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/GateReference.java index 382a7ef2b33bb24cd59f401daa41a2c4f03b2a01..5acd161daa2b9502f57a6485a233b57ad83b892b 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/GateReference.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/GateReference.java @@ -20,7 +20,7 @@ public interface GateReference { GateTypeKind getGateTypeKind(); - Element getComponent(); + NamedElement getComponent(); NamedElement getComponentType(); diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/Reporter.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/Reporter.java index ccef6feb24a79708c7c6926080b7e86e67923b3a..7670725ad86ca94f01a63f53a455e2e321032234 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/Reporter.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/Reporter.java @@ -7,46 +7,47 @@ public interface Reporter { /** * Log comments as specified in TDL model. Comments are logged before the * execution of the associated element. + * @param tester Name of the reporting tester component. */ - void comment(String body); + void comment(String tester, String body); /** * Log test objective associated with a behaviour element as specified in TDL * model. Test objectives are logged after the execution of the associated * behaviour. - * + * @param tester Name of the reporting tester component. * @param uri URI of the objective. * @param description Description of the objective. */ - void testObjectiveReached(String uri, String description); + void testObjectiveReached(String tester, String uri, String description); /** * Log the start of a behaviour execution. - * + * @param tester Name of the reporting tester component. * @param kind Name of behaviour element meta-class as specified in TDL. * @param id Locally unique identifier of the behaviour element (to be - * matched with {@link #behaviourCompleted(String) + * matched with {@link #behaviourCompleted(String, String) * behaviourCompleted()}). * @param properties Any behaviour specific properties. */ - void behaviourStarted(String kind, String id, Object... properties); + void behaviourStarted(String tester, String kind, String id, Object... properties); /** * Log the completion of a behaviour execution. - * + * @param tester Name of the reporting tester component. * @param id Locally unique identifier of the behaviour element (to be matched - * with {@link #behaviourStarted(String, String, Object...) + * with {@link #behaviourStarted(String, String, String, Object...) * behaviourStarted()}). */ - void behaviourCompleted(String id); + void behaviourCompleted(String tester, String id); /** * Log a runtime error. Runtime errors result in the termination of test * execution. Note that it is not the responsibility of the logger to handle the * errors in any way except logging them. - * + * @param tester Name of the reporting tester component. * @param t The exception that was thrown by the execution engine or any of the * adapters. */ - void runtimeError(Throwable t); + void runtimeError(String tester, Throwable t); } diff --git a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/SystemAdapter.java b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/SystemAdapter.java index 4f6f09d0a78b95cb27ffb434d7fbeefbc038a580..db0433d0278d2b332d9b3136a079fdd3c5ff8a91 100644 --- a/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/SystemAdapter.java +++ b/plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/tri/SystemAdapter.java @@ -19,8 +19,9 @@ public interface SystemAdapter { * Prepare the adapter for all connections configured for an upcoming test * description execution. This method is called before any test behaviour is * executed and is a good place for doing any necessary initialization. + * @param component The component for which the connections are configured. */ - void configure(Connection[] connections); + void configure(Connection[] connections, NamedElement component); /** * Encode and send the data to system under test using protocol or adapter @@ -28,8 +29,9 @@ public interface SystemAdapter { * * @param message The data to be sent. * @param connection The connection on which the message is to be sent. + * @param source The component that sends the message. */ - void send(Data message, Connection connection); + void send(Data message, Connection connection, NamedElement source); /** * Blocks until incoming data is available and tries to decode the first @@ -48,13 +50,14 @@ public interface SystemAdapter { * match against. If null then returns any data that is * available after decoding. * @param connection The connection on which the message is to be received. + * @param target The component that receives the message. * @return The data in expected format or null if most recent data didn't match * the expected one. * @throws InterruptedException If the waiting thread is interrupted. * @throws AssertionError If the received data didn't match the expected * data. */ - Data receive(Data expected, Connection connection) throws InterruptedException, AssertionError; + Data receive(Data expected, Connection connection, NamedElement target) throws InterruptedException, AssertionError; /** * Calls a remote procedure and blocks until reply is received or exception is @@ -76,18 +79,19 @@ public interface SystemAdapter { * and value to match against. * @param connection The connection on which the procedure is to be * called. + * @param source The component that calls the procedure. * @return The reply or exception in expected format. * @throws InterruptedException If the waiting thread is interrupted. * @throws AssertionError If the received reply or exception didn't match * the expected data. */ Data call(Procedure operation, Argument[] arguments, Data expectedReturn, Data expectedException, - Connection connection) throws InterruptedException, AssertionError; + Connection connection, NamedElement source) throws InterruptedException, AssertionError; /** - * @see #receive(Data, Connection) + * @see #receive(Data, Connection, NamedElement) */ - Data[] receiveCall(Procedure operation, Data[] expectedArguments, Connection connection) + Data[] receiveCall(Procedure operation, Data[] expectedArguments, Connection connection, NamedElement target) throws InterruptedException, AssertionError; /** @@ -98,8 +102,9 @@ public interface SystemAdapter { * @param reply The reply to be sent. * @param exception The exception to be raised. * @param connection The connection on which the response is to be sent. + * @param source The component that sends the reply. */ - void replyCall(Procedure operation, Data reply, Data exception, Connection connection); + void replyCall(Procedure operation, Data reply, Data exception, Connection connection, NamedElement source); /** * XXX do we need this? diff --git a/plugins/org.etsi.mts.tdl.execution.java/.classpath b/plugins/org.etsi.mts.tdl.execution.java/.classpath index 982b373f3da01fedd6e15ae36acefadea1aaf3d1..8285aee215856482ff883795e3ca4969fa33ff79 100644 --- a/plugins/org.etsi.mts.tdl.execution.java/.classpath +++ b/plugins/org.etsi.mts.tdl.execution.java/.classpath @@ -1,12 +1,7 @@ - - - - - - + diff --git a/plugins/org.etsi.mts.tdl.execution.java/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.execution.java/.settings/org.eclipse.jdt.core.prefs index 6de7763da58418b007110a107e3131ac59272ac1..5717c0241a73df3ce9baa485477dbbabd39e30e2 100644 --- a/plugins/org.etsi.mts.tdl.execution.java/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.execution.java/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,8 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -13,4 +13,4 @@ org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.processAnnotations=disabled org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.execution.java/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.execution.java/META-INF/MANIFEST.MF index b8ed33c489a8dee5ac5f00001726aa9382b11a67..3a3744edf63312c4c5b3b9108f432055b7b615ac 100644 --- a/plugins/org.etsi.mts.tdl.execution.java/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.execution.java/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-SymbolicName: org.etsi.mts.tdl.execution.java;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-ClassPath: . Automatic-Module-Name: org.etsi.mts.tdl.execution.java -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: . Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, @@ -15,5 +15,10 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.emf.ecore, org.etsi.mts.tdl.model, org.etsi.mts.tdl.execution.java.codegen, - junit-jupiter-api + junit-jupiter-api, + org.eclipse.debug.core, + org.eclipse.debug.ui, + org.eclipse.jdt.core, + org.eclipse.jdt.launching, + org.eclipse.xtext diff --git a/plugins/org.etsi.mts.tdl.execution.java/plugin.xml b/plugins/org.etsi.mts.tdl.execution.java/plugin.xml index d6deab7396eabeaf450a7606348d83ab16e4ff08..30c14f41c89b27cf0e760d861a108b9d7098e8a1 100644 --- a/plugins/org.etsi.mts.tdl.execution.java/plugin.xml +++ b/plugins/org.etsi.mts.tdl.execution.java/plugin.xml @@ -9,6 +9,8 @@ + + + + + + + + + + + + + @@ -42,4 +62,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/Activator.java b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/Activator.java new file mode 100644 index 0000000000000000000000000000000000000000..714c1ce222055055319bf00c8ce3734a3f28d7ba --- /dev/null +++ b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/Activator.java @@ -0,0 +1,30 @@ +package org.etsi.mts.tdl.execution.java.eclipse.commands; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * Standard OSGi/Eclipse bundle activator. + */ +public class Activator extends AbstractUIPlugin { + + public static final String PLUGIN_ID = "com.example.tdltx.junitrunner"; //$NON-NLS-1$ + + private static Activator plugin; + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + public static Activator getDefault() { + return plugin; + } +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/JUnitTestDescriptor.java b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/JUnitTestDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..1bc649fcbebe0630e611eb5397d6885636adbf5b --- /dev/null +++ b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/JUnitTestDescriptor.java @@ -0,0 +1,66 @@ +package org.etsi.mts.tdl.execution.java.eclipse.commands; + +/** + * Describes one predefined JUnit test that can be selected and launched. + * + *

Extend {@link PredefinedTests} to add more entries; no other class + * needs to change. + */ +public final class JUnitTestDescriptor { + + /** Human-readable label shown in the selection dialog. */ + private final String label; + + /** + * Fully-qualified class name of the JUnit test class, + * e.g. {@code com.example.myapp.tests.MyFeatureTest}. + */ + private final String testClassName; + + /** + * Optional method name. When {@code null} the whole class is run. + * When set, only that single test method is run, + * e.g. {@code testParseValidDocument}. + */ + private final String testMethodName; + + private final String testObjective; + + // ----------------------------------------------------------------------- + + /** + * Creates a descriptor for running an entire test class. + */ + public JUnitTestDescriptor(String label, String testClassName) { + this(label, testClassName, null, null); + } + + public JUnitTestDescriptor(String label, String testClassName, String testMethodName) { + this(label, testClassName, testMethodName, null); + } + + + /** + * Creates a descriptor for running a single test method. + */ + public JUnitTestDescriptor(String label, String testClassName, String testMethodName, String testObjective) { + this.label = label; + this.testClassName = testClassName; + this.testMethodName = testMethodName; + this.testObjective = testObjective; + } + + // ----------------------------------------------------------------------- + + public String getLabel() { return label; } + public String getTestClassName() { return testClassName; } + public String getTestMethodName() { return testMethodName; } + public String getTestObjective() { return testObjective; } + + /** Returns {@code true} when only a single method should be executed. */ + public boolean hasSingleMethod() { return testMethodName != null && !testMethodName.isEmpty(); } + public boolean hastestObjective() { return testObjective != null && !testObjective.isEmpty(); } + + @Override + public String toString() { return label; } +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/RenderHandler.java b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/RenderHandler.java index a9a05cf7e4b5cf95288a8f341f1fa32ab34fd159..90788bb300e9abb7cc521d9cd9707088d941b429 100644 --- a/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/RenderHandler.java +++ b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/RenderHandler.java @@ -25,7 +25,9 @@ import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorInput; import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.part.FileEditorInput; import org.etsi.mts.tdl.Package; import org.etsi.mts.tdl.execution.java.codegen.JUnitTestGenerator; import org.etsi.mts.tdl.execution.java.codegen.Settings; @@ -39,7 +41,10 @@ public class RenderHandler extends AbstractHandler implements IHandler { IFile tdl = null; ISelection selection = HandlerUtil.getCurrentSelection(event); - if (selection instanceof IStructuredSelection && !selection.isEmpty()) { + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + if (input != null && input instanceof FileEditorInput) { + tdl = ((FileEditorInput) input).getFile(); + } else if (selection instanceof IStructuredSelection && !selection.isEmpty()) { Object element = ((IStructuredSelection) selection).getFirstElement(); if (element instanceof IFile) { String ext = ((IFile) element).getFileExtension(); @@ -69,7 +74,8 @@ public class RenderHandler extends AbstractHandler implements IHandler { preferences.get(Settings.INJECTOR, ""), preferences.get(Settings.DATE_FORMAT, ""), preferences.get(Settings.USE_MAPPING, ""), - preferences.getBoolean(Settings.UNMAPPED_DATA, false)); + preferences.getBoolean(Settings.UNMAPPED_DATA, false), + preferences.getBoolean(Settings.LOG_BEHAVIOUR_TRACES, false)); JUnitTestGenerator generator = new JUnitTestGenerator(model, settings); diff --git a/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/RunJUnitTestHandler.java b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/RunJUnitTestHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..a0922b5a72d6eb1edf19597a19011339eb957742 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/RunJUnitTestHandler.java @@ -0,0 +1,286 @@ +package org.etsi.mts.tdl.execution.java.eclipse.commands; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.resource.XtextResourceSet; +import org.etsi.mts.tdl.Package; +import org.etsi.mts.tdl.TestDescription; +import org.etsi.mts.tdl.execution.java.codegen.Settings; +import org.etsi.mts.tdl.execution.java.eclipse.ui.PropertyPage; +import org.osgi.service.prefs.Preferences; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * Handles the "Run Specific JUnit Test…" command. + * + *

    + *
  1. Determines the {@link IProject} from either the active editor or the + * current selection in the Navigator/Package Explorer.
  2. + *
  3. Opens {@link SelectJUnitTestDialog} with the entries from + * {@link PredefinedTests}.
  4. + *
  5. Creates (or re-uses) a JUnit launch configuration for the chosen + * test and launches it in run mode.
  6. + *
+ */ +public class RunJUnitTestHandler extends AbstractHandler { + + /** ID of the JUnit 5 launch config type bundled with org.eclipse.jdt.junit. */ + private static final String JUNIT_LAUNCH_CONFIG_TYPE = + "org.eclipse.jdt.junit.launchconfig"; //$NON-NLS-1$ + + // ----------------------------------------------------------------------- + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event); + + // ── 1. Resolve the project ────────────────────────────────────────── + IProject project = resolveProject(event); + if (project == null) { + showError(window, "No Project Found", + "Could not determine the project for the selected .tdltx file."); + return null; + } + + //TODO: this should be extracted as it is duplicated across all handlers.. + + ISelection selection = HandlerUtil.getCurrentSelection(event); + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + IFile file = null; + if (input != null && input instanceof FileEditorInput) { + file = ((FileEditorInput) input).getFile(); + } else if (selection !=null && selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + Object firstElement = structuredSelection.getFirstElement(); + if (firstElement instanceof IFile) { + file = (IFile) firstElement; + } + } + + if (file == null) { + //TODO: error message + return null; + } + URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); + Injector injector = Guice.createInjector(); + XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class); + XtextResourceSet rs = resourceSet; + Resource r = rs.getResource(uri, true); + EcoreUtil.resolveAll(r); + + Package p = (Package) r.getContents().get(0); + List tests = EcoreUtil2.getAllContentsOfType(r, TestDescription.class); + + ProjectScope ps = new ProjectScope(project); + Preferences preferences = ps.getNode(PropertyPage.PREFERENCE_SCOPE); + String targetPackage = preferences.get(Settings.PACKAGE, ""); + + + // ── 2. Open the selection dialog ──────────────────────────────────── + + List all = tests.stream() + .filter(TestDescription::isIsLocallyOrdered) + .map(t -> new JUnitTestDescriptor( + t.getName(), + targetPackage+ + "." + +p.getName().toLowerCase() + +"." + +t.getName(), + "test_"+t.getName(), + t.getTestObjective().isEmpty() ? null : t.getTestObjective().getFirst().getDescription()) + ) + .toList(); + //TODO: refine display + SelectJUnitTestDialog dialog = + new SelectJUnitTestDialog(window.getShell(), all); + + if (dialog.open() != IDialogConstants.OK_ID) { + return null; // user cancelled + } + + JUnitTestDescriptor chosen = dialog.getSelectedTest(); + if (chosen == null) { + return null; + } + + // ── 3. Launch the chosen test ──────────────────────────────────────── + try { + launchJUnitTest(project, chosen); + } catch (CoreException e) { + Activator.getDefault().getLog().log( + new Status(IStatus.ERROR, Activator.PLUGIN_ID, + "Failed to launch JUnit test: " + chosen.getLabel(), e)); + ErrorDialog.openError(window.getShell(), "Launch Failed", + "An error occurred while launching the JUnit test.", e.getStatus()); + } + + return null; + } + + // ----------------------------------------------------------------------- + // Project resolution helpers + // ----------------------------------------------------------------------- + + /** + * Tries to find an {@link IProject} from the active editor input first, + * then falls back to the current workbench selection. + */ + private IProject resolveProject(ExecutionEvent event) { + + // Try editor input + IEditorInput editorInput = HandlerUtil.getActiveEditorInput(event); + if (editorInput instanceof IFileEditorInput) { + IFile file = ((IFileEditorInput) editorInput).getFile(); + if (file != null) { + return file.getProject(); + } + } + + // Try current selection (Navigator / Package Explorer) + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection instanceof IStructuredSelection) { + Object first = ((IStructuredSelection) selection).getFirstElement(); + if (first instanceof IFile) { + return ((IFile) first).getProject(); + } + if (first instanceof IProject) { + return (IProject) first; + } + } + + return null; + } + + // ----------------------------------------------------------------------- + // JUnit launch configuration + // ----------------------------------------------------------------------- + + /** + * Creates (or reuses an existing) JUnit launch configuration and runs it. + * + *

Configuration names follow the pattern: + * {@code – } + * so multiple predefined tests can coexist without colliding.

+ */ + private void launchJUnitTest(IProject project, JUnitTestDescriptor test) + throws CoreException { + + ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); + ILaunchConfigurationType type = + manager.getLaunchConfigurationType(JUNIT_LAUNCH_CONFIG_TYPE); + + String configName = project.getName() + " – " + test.getLabel(); + + // Re-use an existing config with the same name (avoids proliferation) + ILaunchConfiguration existing = findExistingConfig(manager, type, configName); + ILaunchConfiguration config; + + if (existing != null) { + config = existing; + } else { + config = createLaunchConfig(type, configName, project, test); + } + + DebugUITools.launch(config, ILaunchManager.RUN_MODE); + } + + private ILaunchConfiguration findExistingConfig( + ILaunchManager manager, + ILaunchConfigurationType type, + String name) throws CoreException { + + for (ILaunchConfiguration cfg : manager.getLaunchConfigurations(type)) { + if (cfg.getName().equals(name)) { + return cfg; + } + } + return null; + } + + private ILaunchConfiguration createLaunchConfig( + ILaunchConfigurationType type, + String name, + IProject project, + JUnitTestDescriptor test) throws CoreException { + + ILaunchConfigurationWorkingCopy wc = type.newInstance(null, name); + + // Project + wc.setAttribute( + IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, + project.getName()); + + // Test class + wc.setAttribute( + IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, + test.getTestClassName()); + + // Optional: single test method + if (test.hasSingleMethod()) { + wc.setAttribute( + "org.eclipse.jdt.junit.TESTNAME", //$NON-NLS-1$ + test.getTestMethodName()); + } + + // JUnit 5 runner (change to "4" for JUnit 4, or "" for auto-detect) + wc.setAttribute("org.eclipse.jdt.junit.TEST_KIND", "org.eclipse.jdt.junit.loader.junit5"); //$NON-NLS-1$ //$NON-NLS-2$ + + // Keep source locator + wc.setAttribute( + IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER, + "org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"); //$NON-NLS-1$ + + return wc.doSave(); + } + + // ----------------------------------------------------------------------- + // Utility + // ----------------------------------------------------------------------- + + private void showError(IWorkbenchWindow window, String title, String message) { + ErrorDialog.openError( + window.getShell(), title, message, + new Status(IStatus.ERROR, Activator.PLUGIN_ID, message)); + } +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/SelectJUnitTestDialog.java b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/SelectJUnitTestDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..b1ce64d485c7048049c8e9c52f70bc777db46c34 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/commands/SelectJUnitTestDialog.java @@ -0,0 +1,139 @@ +package org.etsi.mts.tdl.execution.java.eclipse.commands; + +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * Modal dialog that displays the list of predefined JUnit tests and lets the + * user pick exactly one to execute. + * + *

After {@link #open()} returns {@link IDialogConstants#OK_ID} call + * {@link #getSelectedTest()} to retrieve the chosen descriptor.

+ */ +public class SelectJUnitTestDialog extends Dialog { + + private final List tests; + private ListViewer listViewer; + private JUnitTestDescriptor selectedTest; + + // ----------------------------------------------------------------------- + + public SelectJUnitTestDialog(Shell parentShell, List tests) { + super(parentShell); + this.tests = tests; + setShellStyle(getShellStyle() | SWT.RESIZE); + } + + // ----------------------------------------------------------------------- + // Shell / title + // ----------------------------------------------------------------------- + + @Override + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText("Run Specific JUnit Test"); + } + + // ----------------------------------------------------------------------- + // UI construction + // ----------------------------------------------------------------------- + + @Override + protected Control createDialogArea(Composite parent) { + Composite container = (Composite) super.createDialogArea(parent); + container.setLayout(new GridLayout(1, false)); + + // Description label + Label label = new Label(container, SWT.WRAP); + label.setText("Select a predefined JUnit test to run:"); + label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + // List of tests + listViewer = new ListViewer(container, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL); + listViewer.setContentProvider(ArrayContentProvider.getInstance()); + listViewer.setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + if (element instanceof JUnitTestDescriptor) { + JUnitTestDescriptor d = (JUnitTestDescriptor) element; + // Show class (+ optional method) as a subtitle +// String subtitle = d.hasSingleMethod() +// ? d.getTestClassName() + "#" + d.getTestMethodName() +// : d.getTestClassName(); + String subtitle = d.hastestObjective() + ? ": "+d.getTestObjective() + : ""; + return d.getLabel() + subtitle; + } + return super.getText(element); + } + }); + listViewer.setInput(tests); + + GridData listGD = new GridData(SWT.FILL, SWT.FILL, true, true); + listGD.heightHint = 200; + listGD.widthHint = 550; + listViewer.getControl().setLayoutData(listGD); + + // Pre-select first item so the OK button is immediately usable + if (!tests.isEmpty()) { + listViewer.setSelection(new StructuredSelection(tests.get(0)), true); + } + + // Double-click confirms selection + listViewer.addDoubleClickListener(event -> okPressed()); + + // Enable/disable OK button depending on whether something is selected + listViewer.addSelectionChangedListener(event -> + getButton(IDialogConstants.OK_ID).setEnabled( + !listViewer.getSelection().isEmpty())); + + return container; + } + + // ----------------------------------------------------------------------- + // OK / Cancel + // ----------------------------------------------------------------------- + + @Override + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + // OK starts enabled because we pre-select the first item + getButton(IDialogConstants.OK_ID).setEnabled(!tests.isEmpty()); + } + + @Override + protected void okPressed() { + IStructuredSelection sel = (IStructuredSelection) listViewer.getSelection(); + if (!sel.isEmpty()) { + selectedTest = (JUnitTestDescriptor) sel.getFirstElement(); + } + super.okPressed(); + } + + // ----------------------------------------------------------------------- + // Result accessor + // ----------------------------------------------------------------------- + + /** + * Returns the test chosen by the user, or {@code null} if the dialog + * was cancelled or nothing was selected. + */ + public JUnitTestDescriptor getSelectedTest() { + return selectedTest; + } +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/ui/PropertyPage.java b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/ui/PropertyPage.java index 6211bf74a2e93aeff31d39213ad1d01715b2f00d..1edc4d87a1675a7ebece65dd5f561b8ad9edec75 100644 --- a/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/ui/PropertyPage.java +++ b/plugins/org.etsi.mts.tdl.execution.java/src/org/etsi/mts/tdl/execution/java/eclipse/ui/PropertyPage.java @@ -130,6 +130,9 @@ public class PropertyPage extends FieldEditorPreferencePage implements IWorkbenc BooleanFieldEditor unmappedData = new BooleanFieldEditor(Settings.UNMAPPED_DATA, "Use unmapped data", parent); addField(unmappedData); + BooleanFieldEditor logBehaviourTraces = new BooleanFieldEditor(Settings.LOG_BEHAVIOUR_TRACES, "Log behaviour traces", parent); + addField(logBehaviourTraces); + } private boolean isValid(FieldEditor e) { diff --git a/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/.classpath b/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/.classpath index 64d7e24a90c5a8561da9c7161df2407173e12250..1d94f3b120459d46d562da1195869df09f9ddf3a 100644 --- a/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/META-INF/MANIFEST.MF index bfae79ec1686dea1ddb1a0c436fd323ce8e30f19..24842b5271a76918deadb12d03eaa7675c6ee495 100644 --- a/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.graphical.labels.data.ui/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.graphical.labels.data.ui Bundle-Name: TDL Graphical Editor Labels UI Bundle-Vendor: TDL Graphical Editor Bundle-Version: 1.0.0.qualifier @@ -18,7 +19,7 @@ Require-Bundle: org.etsi.mts.tdl.graphical.labels.data;visibility:=reexport, org.eclipse.compare, org.antlr.runtime;bundle-version="[3.2.0,3.2.1)" Import-Package: org.apache.log4j -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.graphical.labels.ui.quickfix, org.etsi.mts.tdl.graphical.labels.ui.contentassist, org.etsi.mts.tdl.graphical.labels.data.ui.internal, diff --git a/plugins/org.etsi.mts.tdl.graphical.labels.data/.classpath b/plugins/org.etsi.mts.tdl.graphical.labels.data/.classpath index 64d7e24a90c5a8561da9c7161df2407173e12250..1d94f3b120459d46d562da1195869df09f9ddf3a 100644 --- a/plugins/org.etsi.mts.tdl.graphical.labels.data/.classpath +++ b/plugins/org.etsi.mts.tdl.graphical.labels.data/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.graphical.labels.data/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.graphical.labels.data/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.graphical.labels.data/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.graphical.labels.data/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.graphical.labels.data/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.graphical.labels.data/META-INF/MANIFEST.MF index 1f9797b85a2675caf0a1dbbde3b0f91bd71b2d2d..dee56217ac86573b9e0d96b6f214b9f1d11dbbea 100644 --- a/plugins/org.etsi.mts.tdl.graphical.labels.data/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.graphical.labels.data/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.graphical.labels.data Bundle-Name: TDL Graphical Editor Labels Bundle-Vendor: TDL Graphical Editor Bundle-Version: 1.0.0.qualifier @@ -14,7 +15,7 @@ Require-Bundle: org.eclipse.xtext;visibility:=reexport, org.objectweb.asm;resolution:=optional, org.etsi.mts.tdl.model Import-Package: org.apache.log4j -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.graphical.labels, org.etsi.mts.tdl.graphical.labels.services, org.etsi.mts.tdl.graphical.labels.serializer, diff --git a/plugins/org.etsi.mts.tdl.graphical.labels.data/build.properties b/plugins/org.etsi.mts.tdl.graphical.labels.data/build.properties index c3f7d802dd6f7f7bb62109ca0d3e0c5232b0078c..420525d4708dcaf3722a86bf8e12406cf6d2d8ba 100644 --- a/plugins/org.etsi.mts.tdl.graphical.labels.data/build.properties +++ b/plugins/org.etsi.mts.tdl.graphical.labels.data/build.properties @@ -3,7 +3,7 @@ source.. = src/,\ bin.includes = META-INF/,\ . additional.bundles = org.eclipse.xtext.xbase,\ - org.eclipse.xtext.generator,\ + org.eclipse.xtext.xtext.generator,\ org.apache.commons.logging,\ org.eclipse.emf.codegen.ecore,\ org.eclipse.emf.mwe.utils,\ diff --git a/plugins/org.etsi.mts.tdl.graphical.viewpoint/.classpath b/plugins/org.etsi.mts.tdl.graphical.viewpoint/.classpath index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.graphical.viewpoint/.classpath +++ b/plugins/org.etsi.mts.tdl.graphical.viewpoint/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.graphical.viewpoint/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.graphical.viewpoint/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.graphical.viewpoint/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.graphical.viewpoint/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.graphical.viewpoint/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.graphical.viewpoint/META-INF/MANIFEST.MF index cf5563541993686778b06c62672dc5ff775c3be5..0622361e6f8e48700604303f0961bc6bc31230e4 100644 --- a/plugins/org.etsi.mts.tdl.graphical.viewpoint/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.graphical.viewpoint/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.graphical.viewpoint Bundle-Name: %pluginName Bundle-SymbolicName: org.etsi.mts.tdl.graphical.viewpoint;singleton:=true Bundle-Version: 0.9.0.qualifier @@ -33,4 +34,4 @@ Require-Bundle: org.eclipse.ui, org.eclipse.sirius.properties.ext.widgets.reference.edit, org.eclipse.sirius.ui.properties.ext.widgets.reference Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 diff --git a/plugins/org.etsi.mts.tdl.graphical.viewpoint/icons/new_TDLgr_proj.gif b/plugins/org.etsi.mts.tdl.graphical.viewpoint/icons/new_TDLgr_proj.gif new file mode 100644 index 0000000000000000000000000000000000000000..984bc91396e28d92b957e4661e1b6249caecca6f Binary files /dev/null and b/plugins/org.etsi.mts.tdl.graphical.viewpoint/icons/new_TDLgr_proj.gif differ diff --git a/plugins/org.etsi.mts.tdl.graphical.viewpoint/plugin.xml b/plugins/org.etsi.mts.tdl.graphical.viewpoint/plugin.xml index 0d2ed8bd3adcbfad1ea5fafb79ade2a46c5b9537..b224435b544340b72532a7af7a2919501a11a1ca 100644 --- a/plugins/org.etsi.mts.tdl.graphical.viewpoint/plugin.xml +++ b/plugins/org.etsi.mts.tdl.graphical.viewpoint/plugin.xml @@ -87,16 +87,15 @@ - - + + diff --git a/plugins/org.etsi.mts.tdl.helper/.classpath b/plugins/org.etsi.mts.tdl.helper/.classpath index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.helper/.classpath +++ b/plugins/org.etsi.mts.tdl.helper/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.helper/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.helper/.settings/org.eclipse.jdt.core.prefs index c9545f06a4120d5b4a1228fb19f67a1171bc0f5b..23fa13b170502d5a7f7a0549188dbc454a7cf0c8 100644 --- a/plugins/org.etsi.mts.tdl.helper/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.helper/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.helper/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.helper/META-INF/MANIFEST.MF index eccaded377c38231de25f0e529869aaf6cf256f2..09e7052a266985e03aa769039311c921c6a38c07 100644 --- a/plugins/org.etsi.mts.tdl.helper/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.helper/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-SymbolicName: org.etsi.mts.tdl.helper Bundle-Version: 1.0.0.qualifier Bundle-Vendor: ETSI Automatic-Module-Name: org.etsi.mts.tdl.helper -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Require-Bundle: org.eclipse.xtext, org.etsi.mts.tdl.model, org.eclipse.xtext.xbase, @@ -17,12 +17,11 @@ Require-Bundle: org.eclipse.xtext, org.etsi.mts.tdl.TPLan2, org.etsi.mts.tdl.tx, org.etsi.mts.tdl.txi, + org.eclipse.emf.mwe.utils, org.eclipse.emf.ecore, org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.emf.common, - org.eclipse.emf.mwe.utils, org.eclipse.ocl.xtext.completeocl, - com.google.guava, org.etsi.mts.tdl.common Export-Package: org.etsi.mts.tdl.helper diff --git a/plugins/org.etsi.mts.tdl.helper/src/org/etsi/mts/tdl/helper/DependencyAnalyser.java b/plugins/org.etsi.mts.tdl.helper/src/org/etsi/mts/tdl/helper/DependencyAnalyser.java new file mode 100644 index 0000000000000000000000000000000000000000..3e8f96caa14578fb33ca0f9781ad2ddc19468882 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.helper/src/org/etsi/mts/tdl/helper/DependencyAnalyser.java @@ -0,0 +1,70 @@ +package org.etsi.mts.tdl.helper; + +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +public class DependencyAnalyser { + static List matchesList = new ArrayList(); + + public static void main(String[] args) throws Exception { + PathMatcher matcher = FileSystems.getDefault().getPathMatcher("regex:.*META-INF/MANIFEST\\.MF"); + + try (Stream files = Files.walk(Paths.get("../"))) { + // Filter files that match the pattern + List manifests = files.filter(matcher::matches) + .sorted() + .collect(Collectors.toList()); + for (Path m : manifests) { +// System.out.println(m); + getDependencies(m.toFile()); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + public static void getDependencies(File file) throws Exception{ + Manifest manifest = new Manifest(new FileInputStream(file)); + Attributes attr = manifest.getMainAttributes(); + for (Entry e:attr.entrySet()) { +// System.out.println(e.getKey() + " : "+e.getValue()); + } + String id = (String) attr.getValue("Bundle-SymbolicName"); + String bundles = (String) attr.getValue("Require-Bundle"); + if (bundles != null) { + bundles = bundles.replaceAll(";bundle-version=(\".+?\")", "") + .replaceAll(";resolution:=optional", "") + .replaceAll(";visibility:=reexport", "") + .replaceAll("-", ".") + ; + String[] bundleList = bundles.split(","); + System.out.println(""+id.replaceAll(";.+", "")); + for (String b : bundleList) { + if (!b.startsWith("org.etsi.mts")) { +// System.out.println(id.replaceAll(";.+", "")+"-->"+b); + System.out.println(" "+b); + } + } + } + } +} diff --git a/plugins/org.etsi.mts.tdl.helper/src/org/etsi/mts/tdl/helper/TDLHelper.java b/plugins/org.etsi.mts.tdl.helper/src/org/etsi/mts/tdl/helper/TDLHelper.java index b513c4f42088121fdd85efaa137d22108c9ed886..64d3dea64be21e81b57a573bf3c8ad211fb933a2 100644 --- a/plugins/org.etsi.mts.tdl.helper/src/org/etsi/mts/tdl/helper/TDLHelper.java +++ b/plugins/org.etsi.mts.tdl.helper/src/org/etsi/mts/tdl/helper/TDLHelper.java @@ -2,31 +2,18 @@ package org.etsi.mts.tdl.helper; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.Set; import org.apache.log4j.Level; import org.apache.log4j.Logger; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EOperation; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EValidator; import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.mwe.utils.StandaloneSetup; import org.eclipse.ocl.common.OCLConstants; import org.eclipse.ocl.pivot.internal.delegate.OCLInvocationDelegateFactory; @@ -38,15 +25,13 @@ import org.eclipse.xtext.GrammarUtil; import org.eclipse.xtext.IGrammarAccess; import org.eclipse.xtext.resource.IResourceServiceProvider; import org.eclipse.xtext.resource.XtextResourceSet; -import org.eclipse.xtext.serializer.impl.Serializer; -import org.etsi.mts.tdl.Package; import org.etsi.mts.tdl.TDLan2StandaloneSetup; import org.etsi.mts.tdl.TDLtxStandaloneSetup; import org.etsi.mts.tdl.TDLtxiStandaloneSetup; import org.etsi.mts.tdl.TPLan2StandaloneSetup; import org.etsi.mts.tdl.impl.tdlPackageImpl; +import org.etsi.mts.tdl.resources.ResourceHandler; import org.etsi.mts.tdl.structuredobjectives.impl.StructuredObjectivesPackageImpl; -import org.osgi.framework.Bundle; import com.google.inject.Injector; @@ -83,15 +68,14 @@ public class TDLHelper { * @return A resource loaded from the file. */ public static Resource load(String filename) { - Resource resource = resourceSet.getResource(org.eclipse.emf.common.util.URI.createURI(filename), true); - return resource; + return ResourceHandler.load(filename); } /** * Link / resolve all loaded resources. */ public static void link() { - EcoreUtil.resolveAll(resourceSet); + ResourceHandler.link(); } /** @@ -99,8 +83,7 @@ public class TDLHelper { */ public static void check() { //TODO: check automatically? make optional in case of performance or redundancy concerns? -// TDLHelper.link(); - resourceSet.getResources().forEach(TDLHelper::check); + ResourceHandler.check(); } /** @@ -108,19 +91,16 @@ public class TDLHelper { * @param filename location of the resource to be checked. */ public static void check(String filename) { - Resource r = TDLHelper.load(filename); - check(r); + ResourceHandler.check(filename); } /** * Check resource. * @param r the resource to be checked. */ - private static void check(Resource r) { - r.getErrors().forEach(e -> System.out.println("Error: "+r.getURI().lastSegment()+": "+e.getLine()+": "+e.getMessage())); - r.getWarnings().forEach(e -> System.out.println("Warning: "+r.getURI().lastSegment()+": "+e.getLine()+": "+e.getMessage())); + public static void check(Resource r) { + ResourceHandler.check(r); } - /** * Creates a new resource at the specified location. @@ -129,12 +109,7 @@ public class TDLHelper { * @throws Exception */ public static Resource create(String filename) throws Exception { - Resource existing = resourceSet.getResource(org.eclipse.emf.common.util.URI.createFileURI(filename), false); - if (existing != null) { - existing.delete(Collections.emptyMap()); - } - Resource resource = resourceSet.createResource(org.eclipse.emf.common.util.URI.createFileURI(filename)); - return resource; + return ResourceHandler.create(resourceSet, filename); } /** @@ -143,36 +118,16 @@ public class TDLHelper { * @throws Exception */ public static void store(Resource resource, boolean derived) throws Exception { - if (derived) { - IFile file = resourceToFile(resource); - if (file != null) { - if (!file.exists()) - file.create(new ByteArrayInputStream(new byte[0]), false, null); - file.setDerived(derived, new NullProgressMonitor()); - } - } - resource.save(Collections.emptyMap()); + ResourceHandler.store(resource, derived); } - public static IFile resourceToFile(Resource resource) { - URI uri = resource.getURI(); - return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true))); - } - - /** * Get textual representation of resource contents. * @param resource A resource to be represented. * @throws Exception */ public static String getText(Resource resource) throws Exception { -// if (resource instanceof XtextResource) { -// return NodeModelUtils.getNode(resource.getContents().get(0)).getText(); -// } else { - //TODO: this needs to be more robust for the desired format - Serializer serializer = injector.getInstance(Serializer.class); - return serializer.serialize(resource.getContents().get(0)); -// } + return ResourceHandler.getText(injector, resource); } /** @@ -205,106 +160,7 @@ public class TDLHelper { return GrammarUtil.getAllKeywords(grammarAccess.getGrammar()); return Collections.EMPTY_SET; } - - private static final String TDL_MODEL_NAME = "tdl"; - private static final String HTTP_MODEL_NAME = "http"; - private static final String JAVA_MODEL_NAME = "java"; - private static final String[] MODEL_FILE_EXTENSIONS = new String[] { - "tdl", "tdlan2", "tdltx", "tdltxi" - }; - public static IProject getProjectForResource(Resource resource) { - IWorkspaceRoot ws = org.eclipse.core.resources.ResourcesPlugin.getWorkspace().getRoot(); - URI resourceUri = resource.getURI(); - IFile modelFile = null; - if (resourceUri.isPlatformResource()) { - modelFile = ws.getFile(new Path(resourceUri.toPlatformString(true))); - } else if (resourceUri.isFile()) { - // TODO - modelFile = ws.getFile(new Path(resourceUri.toFileString())); -// String uriString = resourceUri.toFileString(); -// java.net.URI uri = new java.net.URI(uriString); -// IFile[] files = ws.findFilesForLocationURI(uri); - } - if (modelFile != null) - return modelFile.getProject(); - return null; - } - - abstract static class FileFinder implements IResourceVisitor { - - public IFile file; - - @Override - public boolean visit(IResource resource) throws CoreException { - if (file != null) - return false; - if (resource.getType() != IResource.FILE) - return true; - if (mathces((IFile) resource)) { - this.file = (IFile) resource; - } - return file == null; - } - - abstract protected boolean mathces(IFile file); - } - - public static Package getTdlPackage(Resource resource) { - return getKnownPackage(resource, TDL_MODEL_NAME); - } - - public static Package getHttpPackage(Resource resource) { - return getKnownPackage(resource, HTTP_MODEL_NAME); - } - - public static Package getJavaPackage(Resource resource) { - return getKnownPackage(resource, JAVA_MODEL_NAME); - } - - private static Package getKnownPackage(Resource resource, String packageName) { - try { - IProject prj = getProjectForResource(resource); - if (prj != null) { - final Set names = new HashSet<>(); - for (String ext : MODEL_FILE_EXTENSIONS) { - names.add(packageName + "." + ext); - } - FileFinder finder = new FileFinder() { - @Override - protected boolean mathces(IFile file) { - return names.contains(file.getName().toLowerCase()); - } - }; - prj.accept(finder); - if (finder.file != null) { - URI uri = URI.createPlatformResourceURI(finder.file.getFullPath().toString(), true); - Resource tdlResource = resource.getResourceSet().getResource(uri, true); - return (Package) tdlResource.getContents().get(0); - } else { - //TODO: somewhat hacky way to load resources from the library if not found locally - if (Platform.isRunning()) { - Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.library"); - ArrayList packages = new ArrayList<>(); - bundle.findEntries("/","*.tdltx", true).asIterator().forEachRemaining(e-> { - org.eclipse.emf.common.util.URI pURI = org.eclipse.emf.common.util.URI.createURI(e.toString()); - if (names.contains(pURI.lastSegment().toLowerCase())) { - Resource tdlResource = resource.getResourceSet().getResource(pURI, true); - packages.add((Package) tdlResource.getContents().get(0)); - } - }); - return packages.get(0); - } - } - } - } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - throw new RuntimeException(e); - } - return null; - } - /** * Reset the shared resourceSet. */ diff --git a/plugins/org.etsi.mts.tdl.importers.ui/.classpath b/plugins/org.etsi.mts.tdl.importers.ui/.classpath index 685a6999c9acba0d0158b0929d7a4d384644452e..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.importers.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.importers.ui/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.importers.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.importers.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..cc4eaa539c5f4b0f916828ed253989682ceaf93c --- /dev/null +++ b/plugins/org.etsi.mts.tdl.importers.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.importers.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.importers.ui/META-INF/MANIFEST.MF index 58883f63eb5b2405df25661d7ea0df10e409c63c..047f8742bea90cc2f3addbb7265185aa7697de3c 100644 --- a/plugins/org.etsi.mts.tdl.importers.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.importers.ui/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.importers.ui Bundle-Name: TDL Importers UI Bundle-SymbolicName: org.etsi.mts.tdl.importers.ui;singleton:=true Bundle-Version: 1.0.0.qualifier @@ -10,18 +11,11 @@ Require-Bundle: org.eclipse.ui, org.eclipse.ui.editors;bundle-version="3.5.0", org.eclipse.ui.ide;bundle-version="3.5.0", org.eclipse.ui.workbench, - com.google.inject, org.eclipse.xtext.ui, org.eclipse.emf.ecore, org.eclipse.xtext, org.etsi.mts.tdl.model, - org.etsi.mts.tdl.common, - org.etsi.mts.tdl.asn2tdl, - org.etsi.mts.tdl.openapi2tdl.next, - org.etsi.mts.tdl.to2tdl, - org.etsi.mts.tdl.json2tdl, - org.etsi.mts.tdl.yang2tdl, - org.etsi.mts.tdl.helper + org.etsi.mts.tdl.common Bundle-ActivationPolicy: lazy Import-Package: org.eclipse.emf.common.util -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 diff --git a/plugins/org.etsi.mts.tdl.importers.ui/icons/DocIcon.png b/plugins/org.etsi.mts.tdl.importers.ui/icons/DocIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..3d7ad62ab18a465e7c5a1e23b190876810e554f5 Binary files /dev/null and b/plugins/org.etsi.mts.tdl.importers.ui/icons/DocIcon.png differ diff --git a/plugins/org.etsi.mts.tdl.importers.ui/icons/ImportIcon.png b/plugins/org.etsi.mts.tdl.importers.ui/icons/ImportIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f87a208ae189e9fb49a64b977f6738bd63c5fc0 Binary files /dev/null and b/plugins/org.etsi.mts.tdl.importers.ui/icons/ImportIcon.png differ diff --git a/plugins/org.etsi.mts.tdl.importers.ui/plugin.xml b/plugins/org.etsi.mts.tdl.importers.ui/plugin.xml index 8be13466470c0e31b01db2c0f4ab44ebe9e8d347..247ce7471fa29f7f634cd1d2122034d401642088 100644 --- a/plugins/org.etsi.mts.tdl.importers.ui/plugin.xml +++ b/plugins/org.etsi.mts.tdl.importers.ui/plugin.xml @@ -30,15 +30,6 @@ class="org.etsi.mts.tdl.importers.ui.handlers.DocumentationHandler"> - - - - @@ -66,13 +57,13 @@ id="org.etsi.mts.tdl.importers.ui.toolbars.translate"> diff --git a/plugins/org.etsi.mts.tdl.importers.ui/src/org/etsi/mts/tdl/importers/ui/handlers/DocumentationHandler.java b/plugins/org.etsi.mts.tdl.importers.ui/src/org/etsi/mts/tdl/importers/ui/handlers/DocumentationHandler.java index 4d95cfb4914a6a5b25ed2b126cace181faecacac..c732b6239e85849c4c37ee9601311d7ca1719fb4 100644 --- a/plugins/org.etsi.mts.tdl.importers.ui/src/org/etsi/mts/tdl/importers/ui/handlers/DocumentationHandler.java +++ b/plugins/org.etsi.mts.tdl.importers.ui/src/org/etsi/mts/tdl/importers/ui/handlers/DocumentationHandler.java @@ -1,44 +1,25 @@ package org.etsi.mts.tdl.importers.ui.handlers; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Arrays; -import java.util.LinkedHashMap; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.Platform; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.dialogs.ElementListSelectionDialog; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.xtext.resource.XtextResourceSet; -import org.eclipse.xtext.ui.resource.IResourceSetProvider; -import org.etsi.mts.tdl.Package; -import org.etsi.mts.tdl.asn2tdl.ASN2TDLTranslator; -import org.etsi.mts.tdl.json2tdl.JSON2TDLTranslator; -import org.etsi.mts.tdl.openapi2tdl.next.OpenAPI2TDLTranslatorNext; -import org.etsi.mts.tdl.openapi2tdl.next.doc.Doc; -import org.etsi.mts.tdl.to2tdl.TO2TDLTranslator; -import org.etsi.mts.tdl.transform.AbstractTranslator; +import org.etsi.mts.tdl.transform.ServiceProvider; -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.Provider; +import org.etsi.mts.tdl.transform.Converter; +import org.etsi.mts.tdl.transform.Generator; /** * Our sample handler extends AbstractHandler, an IHandler base class. @@ -79,16 +60,15 @@ public class DocumentationHandler extends AbstractHandler { if (file !=null) { String filepath = file.getLocation().toFile().getAbsolutePath(); - Doc doc = new Doc(); + Generator testDocGenerator = ServiceProvider.getService(Generator.class.getName(), "org.etsi.mts.tdl.openapi2tdl.next"); + String content = testDocGenerator.processToString(filepath, Path.of(filepath+"-RQ-ICS-TSS.md").toString()); try { - //TODO: make configurable - doc.processModel(filepath, true); - Files.writeString(Path.of(filepath+"-RQ-ICS-TSS.md"), doc.getContent()); - } catch (Exception e) { + Files.writeString(Path.of(filepath+"-RQ-ICS-TSS.md"), content); + } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); - showErrorDialog(e); } + } //TODO: throw proper execution exceptions? return null; diff --git a/plugins/org.etsi.mts.tdl.importers.ui/src/org/etsi/mts/tdl/importers/ui/handlers/TranslationHandler.java b/plugins/org.etsi.mts.tdl.importers.ui/src/org/etsi/mts/tdl/importers/ui/handlers/TranslationHandler.java index e53cc9082bbb731e0cad0a1b3c26ea4946ae6cdb..15ad380ae899e0743e5f899af2d92cb3c60ab966 100644 --- a/plugins/org.etsi.mts.tdl.importers.ui/src/org/etsi/mts/tdl/importers/ui/handlers/TranslationHandler.java +++ b/plugins/org.etsi.mts.tdl.importers.ui/src/org/etsi/mts/tdl/importers/ui/handlers/TranslationHandler.java @@ -31,13 +31,9 @@ import org.eclipse.ui.statushandlers.StatusManager; import org.eclipse.xtext.resource.XtextResourceSet; import org.eclipse.xtext.ui.resource.IResourceSetProvider; import org.etsi.mts.tdl.Package; -import org.etsi.mts.tdl.asn2tdl.ASN2TDLTranslator; -import org.etsi.mts.tdl.helper.TDLHelper; -import org.etsi.mts.tdl.json2tdl.JSON2TDLTranslator; -import org.etsi.mts.tdl.openapi2tdl.next.OpenAPI2TDLTranslatorNext; -import org.etsi.mts.tdl.to2tdl.TO2TDLTranslator; +import org.etsi.mts.tdl.resources.ResourceHandler; import org.etsi.mts.tdl.transform.AbstractTranslator; -import org.etsi.mts.tdl.yang2tdl.Yang2TDLTranslator; +import org.etsi.mts.tdl.transform.ServiceProvider; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; @@ -141,16 +137,17 @@ public class TranslationHandler extends AbstractHandler { Resource tr = resourceSet.createResource(targetURI); AbstractTranslator translator = null; if (type.contains("asn")) { - translator = new ASN2TDLTranslator(); + translator = ServiceProvider.getService(AbstractTranslator.class.getName(), "org.etsi.mts.tdl.asn2tdl"); } if (type.contains("json")) { - translator = new JSON2TDLTranslator(); + translator = ServiceProvider.getService(AbstractTranslator.class.getName(), "org.etsi.mts.tdl.json2tdl"); } if (type.contains("yaml")) { - translator = new OpenAPI2TDLTranslatorNext(); + translator = ServiceProvider.getService(AbstractTranslator.class.getName(), "org.etsi.mts.tdl.openapi2tdl.next"); } if (type.contains("yang")) { - translator = new Yang2TDLTranslator(); + translator = ServiceProvider.getService(AbstractTranslator.class.getName(), "org.etsi.mts.tdl.yang2tdl"); +// translator = new Yang2TDLTranslator(); //determine limit for looking for related module definitions //also if linked folders are used if (container == null) { @@ -163,7 +160,7 @@ public class TranslationHandler extends AbstractHandler { container = container.getParent(); } String limit = container.getLocation().toFile().getAbsolutePath(); - ((Yang2TDLTranslator) translator).setLimit(limit); + translator.setLimit(limit); } if (translator != null) { translator.setTargetResource(tr); @@ -187,16 +184,22 @@ public class TranslationHandler extends AbstractHandler { //TODO: cleanup wizards, there should be only one clear way how to do everything Resource r = rs.getResource(uri, true); Package p = (Package) r.getContents().get(0); - translator = new TO2TDLTranslator(); + translator = ServiceProvider.getService(AbstractTranslator.class.getName(), "org.etsi.mts.tdl.to2tdl");; translator.setTargetResource(tr); translator.initTargetResource("generated_from_"+p.getName()); translator.addImports(p); - ((TO2TDLTranslator)translator).transform(p); + try { + translator.translate(filepath); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + showErrorDialog(e); + } } //tr.getContents().addAll(EcoreUtil.copyAll(r.getContents())); try { - TDLHelper.store(tr, true); + ResourceHandler.store(tr, true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/plugins/org.etsi.mts.tdl.json2tdl/.classpath b/plugins/org.etsi.mts.tdl.json2tdl/.classpath index 685a6999c9acba0d0158b0929d7a4d384644452e..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.json2tdl/.classpath +++ b/plugins/org.etsi.mts.tdl.json2tdl/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.json2tdl/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.json2tdl/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.json2tdl/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.json2tdl/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.json2tdl/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.json2tdl/META-INF/MANIFEST.MF index 8dadaade1af4196f5bc6c96c4212eabbee269652..034580f711925b071d9474723d8ef69404afbc19 100644 --- a/plugins/org.etsi.mts.tdl.json2tdl/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.json2tdl/META-INF/MANIFEST.MF @@ -3,10 +3,13 @@ Bundle-ManifestVersion: 2 Bundle-Name: JSON to TDL Translator Bundle-SymbolicName: org.etsi.mts.tdl.json2tdl Bundle-Version: 1.0.0.qualifier -Export-Package: org.etsi.mts.tdl.json2tdl +Bundle-Activator: org.etsi.mts.tdl.json2tdl.Activator Require-Bundle: org.etsi.mts.tdl.common, org.eclipse.emf.ecore, + org.eclipse.core.runtime, org.eclipse.xtext, - org.etsi.mts.tdl.helper, com.google.gson +Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.etsi.mts.tdl.json2tdl +Export-Package: org.etsi.mts.tdl.json2tdl +Import-Package: org.eclipse.core.runtime;version="[3.7.0,4.0.0)" diff --git a/plugins/org.etsi.mts.tdl.json2tdl/src/org/etsi/mts/tdl/json2tdl/Activator.java b/plugins/org.etsi.mts.tdl.json2tdl/src/org/etsi/mts/tdl/json2tdl/Activator.java new file mode 100644 index 0000000000000000000000000000000000000000..a3565e43fbea9496073036cfa53df26055921038 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.json2tdl/src/org/etsi/mts/tdl/json2tdl/Activator.java @@ -0,0 +1,59 @@ +package org.etsi.mts.tdl.json2tdl; + +import java.util.Hashtable; + +import org.etsi.mts.tdl.transform.AbstractTranslator; +import org.etsi.mts.tdl.transform.Converter; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +//public class Activator extends Plugin { +public class Activator implements BundleActivator { + + // The plug-in ID + public static final String PLUGIN_ID = "org.etsi.mts.tdl.json2tdl"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { +// super.start(context); + Hashtable properties = new Hashtable(); + properties.put("type", PLUGIN_ID); + context.registerService(Converter.class.getName(), new JSONConverter(), properties); + context.registerService(AbstractTranslator.class.getName(), new JSON2TDLTranslator(), properties); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; +// super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/plugins/org.etsi.mts.tdl.json2tdl/src/org/etsi/mts/tdl/json2tdl/JSONConverter.java b/plugins/org.etsi.mts.tdl.json2tdl/src/org/etsi/mts/tdl/json2tdl/JSONConverter.java index 08f7ff29d7a7e41249f8c1fd56a4a0bc854e9c08..95dd87e9c6e5137e5e443ed0aaf13460a1e040c3 100644 --- a/plugins/org.etsi.mts.tdl.json2tdl/src/org/etsi/mts/tdl/json2tdl/JSONConverter.java +++ b/plugins/org.etsi.mts.tdl.json2tdl/src/org/etsi/mts/tdl/json2tdl/JSONConverter.java @@ -3,28 +3,40 @@ package org.etsi.mts.tdl.json2tdl; import java.io.File; import org.eclipse.emf.ecore.resource.Resource; -import org.etsi.mts.tdl.helper.TDLHelper; +import org.etsi.mts.tdl.resources.ResourceHandler; +import org.etsi.mts.tdl.transform.Converter; -public class JSONConverter { - public static String processToString(String inputPath, String outputPath) { +public class JSONConverter implements Converter { + public String processToString(String inputPath, String outputPath) { return processToString(inputPath, outputPath, "SOURCE_MAPPING", "TARGET_MAPPING"); } - public static String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) { + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) { System.out.println("Exporting: "+outputPath+ " : "+ new File(outputPath).getAbsolutePath()); JSON2TDLTranslator translator = new JSON2TDLTranslator(); String content = "Package imported {}"; try { - Resource tr = TDLHelper.create(outputPath); + Resource tr = ResourceHandler.create(outputPath); translator.setTargetResource(tr); translator.initTargetResource(translator.cleanName(new File(inputPath).getName())); translator.translate(inputPath); - content = TDLHelper.getText(tr); + content = ResourceHandler.getText(tr); } catch (Exception e) { e.printStackTrace(); } return content; } + @Override + public String getExtension() { + return "json"; + } + + @Override + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping, + boolean inline) { + return processToString(inputPath, outputPath, sourceMapping, targetMapping); + } + } diff --git a/plugins/org.etsi.mts.tdl.library/.classpath b/plugins/org.etsi.mts.tdl.library/.classpath index 685a6999c9acba0d0158b0929d7a4d384644452e..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.library/.classpath +++ b/plugins/org.etsi.mts.tdl.library/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.library/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.library/.settings/org.eclipse.jdt.core.prefs index a58ebdcad300d0a088dcbd63941d2c89e78a4f98..1e0cb16bbc76c98cc42fff6b95cc023b7eb74830 100644 --- a/plugins/org.etsi.mts.tdl.library/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.library/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -12,4 +12,4 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/ASN1.tdltx b/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/ASN1.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..e5303d33e7c2d11179894cc1a6d8acda8cd74825 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/ASN1.tdltx @@ -0,0 +1,95 @@ +Note: "Based on TR 103 119 v1.4.1" +@Version: "1.0.0" +Package ASN1 { + Import all from TDL + + //Constraints + //Specific typed constraints for each type + //Constraint AsnBitString + //Constraint AsnOctetString + //Constraint AsnUtcString + //or + //Generic constraint with corresponding detail in + //the constraint quantifier/qualifier: + //e.g. "[01]+'B" or more generically "AsnBitString"? + Constraint ASN1String + Constraint ASN1DateTime + Constraint ASN1Real + Constraint ASN1ObjectIdentifier + + //Types + //BITSTRING + Type BITSTRING {ASN1String:"[01]+'B"} + //or + //Type BITSTRING {ASN1String:"AsnBitString"} + //or + //Type BITSTRING {AsnBitString} + + //OCTETSTRING + Type OCTETSTRING {ASN1String:"[A-F0-9]+'H"} + //or + //Type OCTETSTRING {AsnOctetString} + //or + //Type OCTETSTRING {ASN1String:"AsnOctetString"} + + //BMPString + Type BMPString {ASN1String} + //IA5String + Type IA5String {ASN1String} + //GeneralString + Type GeneralString {ASN1String} + //GraphicString + Type GraphicString {ASN1String} + //NumericString + Type NumericString {ASN1String: "[0-9\\s]+"} + //PrintableString + Type PrintableString {ASN1String} + //TeletexString + Type TeletexString {ASN1String} + //T61String + Type T61String {ASN1String} + //UniversalString + Type UniversalString {ASN1String} + //UTF8String + Type UTF8String {ASN1String} + //VideotexString + Type VideotexString {ASN1String} + //VisibleString + Type VisibleString {ASN1String} + + //UTCTime + Type UTCTime {ASN1DateTime:"YYMMDDhhmm[ss]Z"} + //Type UTCTime {ASN1String:"YYMMDDhhmm[ss]Z"} + //or + //Type UTCTime {ASN1String:"AsnOctetString"} + //or + //Type UTCTime {ASN1DateTime:"AsnOctetString"} + //or + //Type UTCTime {AsnUtcString} + + //GeneralizedTime + Type GeneralizedTime {ASN1DateTime:"YYYYMMDDHH[MM[SS[.fff]]]Z"} + //DATE + Type DATE {ASN1DateTime:"YYYY-MM-DD"} + //TIME-OF-DAY + Type TimeOfDay {ASN1DateTime:"hh:mm:ss"} + //DATE-TIME + Type DateTime {ASN1DateTime:"YYYY-MM-DDThh:mm:ss"} + //INTEGER + //already defined in TDL -> use that + //Type Integer + //REAL + //originally mapped to string with constraint, would override standard + Type Real {ASN1Real} + //BOOLEAN + //already defined in TDL -> use that + //Type Integer + //NULL + Type Null + //OBJECTIDENTIFIER + Type ObjectIdentifier {ASN1ObjectIdentifier} + + //RELATIVE OBJECT OBJECTIDENTIFIER + //use ObjectIdentifier above + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/HTTP.tdltx b/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/HTTP.tdltx index 7e2c4b71535f0f479bef1421c435f403a0be98b3..1bec3747a58bf9d5d460880dae9f191260f364e0 100644 --- a/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/HTTP.tdltx +++ b/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/HTTP.tdltx @@ -1,6 +1,6 @@ @Version: "1.0.0" Package HTTP { - + Import all from TDL Package MessageBasedConfiguration { Import all from MessageBased Message Gate HTTPGate accepts Request,Response diff --git a/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/TDL.tdltx b/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/TDL.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..34941d39bf2dbe7ed9630eb524cb408a0697a0b6 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/TDL.tdltx @@ -0,0 +1,61 @@ +@Version: "1.8.1" +Package TDL { + + Constraint length + Constraint minLength + Constraint maxLength + Constraint range + Constraint format + Constraint union + Constraint uniontype + + Type Boolean + Type Integer + Type String + Type Verdict + + Boolean ^true + Boolean ^false + Boolean True + Boolean False + + Verdict pass + Verdict fail + Verdict inconclusive + + Time second + + Annotation Master + Annotation MappingName + Annotation Version + Annotation check + Annotation where + Annotation PICS + Annotation PIXIT + + //standard annotations for STO + Annotation Initial conditions + Annotation Expected behaviour + Annotation Final conditions + Annotation Test Purpose Description + Annotation when + Annotation then + + Predefined == returns Boolean + Predefined != returns Boolean + Predefined and returns Boolean + Predefined or returns Boolean + Predefined xor returns Boolean + Predefined not returns Boolean + Predefined < returns Boolean + Predefined > returns Boolean + Predefined <= returns Boolean + Predefined >= returns Boolean + Predefined + + Predefined - + Predefined * + Predefined / + Predefined mod + Predefined size returns Integer + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.model.gen/.classpath b/plugins/org.etsi.mts.tdl.model.gen/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..7931ec26b9119b03ff83dea3426230287acbc979 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/.classpath @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.etsi.mts.tdl.model.gen/.gitignore b/plugins/org.etsi.mts.tdl.model.gen/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/.gitignore @@ -0,0 +1 @@ + diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/.project b/plugins/org.etsi.mts.tdl.model.gen/.project similarity index 54% rename from plugins/org.etsi.mts.tdl.tools.to.docx.ui/.project rename to plugins/org.etsi.mts.tdl.model.gen/.project index a13e9ac37b23ff3b0420efe0bed622609179899f..21fd10cb3d5ca1ee45d1c926ec2db9b218fa88bd 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/.project +++ b/plugins/org.etsi.mts.tdl.model.gen/.project @@ -1,10 +1,37 @@ - org.etsi.mts.tdl.tools.to.docx.ui + org.etsi.mts.tdl.model.gen + + org.eclipse.ocl.pivot.ui.oclbuilder + full,incremental, + + + disabledExtensions + *,essentialocl + + + disabledPaths + bin/**,target/** + + + enabledExtensions + ecore,ocl,oclinecore,oclstdlib,uml + + + enabledPaths + model/** + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + org.eclipse.jdt.core.javabuilder @@ -30,10 +57,12 @@ org.eclipse.m2e.core.maven2Nature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature + org.eclipse.xtext.ui.shared.xtextNature + org.eclipse.ocl.pivot.ui.oclnature - 1681464246871 + 1681412457732 30 diff --git a/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.core.resources.prefs b/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000000000000000000000000000000000..99f26c0203a7844de00dbfc56e6a35d8ed3c022c --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..877f80b9e89a687a78d3ea59339b2ec01607bc19 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled diff --git a/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.m2e.core.prefs b/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/plugins/org.etsi.mts.tdl.model.gen/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.model.gen/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..5f95454a59be19cb2e19a4d45d153157f57f5ab9 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/META-INF/MANIFEST.MF @@ -0,0 +1,28 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.etsi.mts.tdl.model.gen;singleton:=true +Automatic-Module-Name: org.etsi.mts.tdl.model.gen +Bundle-Version: 1.4.0.qualifier +Bundle-ClassPath: . +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Bundle-RequiredExecutionEnvironment: JavaSE-21 +Export-Package: org.etsi.mts.tdl.gen +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.emf.ecore;visibility:=reexport, + org.eclipse.emf.ecore.xmi;visibility:=reexport, + org.eclipse.ocl.pivot;visibility:=reexport, + org.eclipse.ocl.examples.codegen;visibility:=reexport, + org.eclipse.ocl.xtext.essentialocl, + org.eclipse.ocl.xtext.completeocl, + org.eclipse.ocl.ecore, + org.eclipse.emf.codegen.ecore;resolution:=optional, + org.apache.log4j;resolution:=optional, + org.apache.commons.logging;resolution:=optional, + org.eclipse.ocl.xtext.oclinecore, + org.eclipse.emf.mwe2.lib +Eclipse-LazyStart: true +Bundle-ActivationPolicy: lazy +Bundle-Activator: org.etsi.mts.tdl.Activator diff --git a/plugins/org.etsi.mts.tdl.model.gen/build.properties b/plugins/org.etsi.mts.tdl.model.gen/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..acc00a0047e27b1547758955161b2fa8cc696dfb --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/build.properties @@ -0,0 +1,9 @@ +# + +bin.includes = .,\ + META-INF/,\ + plugin.xml,\ + plugin.properties +jars.compile.order = . +source.. = src/ +output.. = target/classes/ diff --git a/plugins/org.etsi.mts.tdl.model.gen/plugin.properties b/plugins/org.etsi.mts.tdl.model.gen/plugin.properties new file mode 100644 index 0000000000000000000000000000000000000000..c3935f440a4c578f16e2b4655116fa667d222be3 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/plugin.properties @@ -0,0 +1,4 @@ +# + +pluginName = TDL Metamodel +providerName = www.etsi.org diff --git a/plugins/org.etsi.mts.tdl.model.gen/plugin.xml b/plugins/org.etsi.mts.tdl.model.gen/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..6cca89dc6394136d69cf1d77af997e9f3a84ed74 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/plugin.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/pom.xml b/plugins/org.etsi.mts.tdl.model.gen/pom.xml similarity index 91% rename from plugins/org.etsi.mts.tdl.tools.to.docx/pom.xml rename to plugins/org.etsi.mts.tdl.model.gen/pom.xml index e416ab866965edd35fcab2ebaf35e0f376f339ba..6e60e037707bb95ea7412ab25e678518073c4feb 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/pom.xml +++ b/plugins/org.etsi.mts.tdl.model.gen/pom.xml @@ -5,9 +5,9 @@ org.etsi.mts.tdl.parent 1.0.0-SNAPSHOT ../../org.etsi.mts.tdl.parent - + - org.etsi.mts.tdl.tools.to.docx + org.etsi.mts.tdl.model.gen eclipse-plugin diff --git a/plugins/org.etsi.mts.tdl.model.gen/src/org/etsi/mts/tdl/gen/EcoreGeneratorCustom.java b/plugins/org.etsi.mts.tdl.model.gen/src/org/etsi/mts/tdl/gen/EcoreGeneratorCustom.java new file mode 100644 index 0000000000000000000000000000000000000000..90414d0d1c11262336c3fbfc168416de9dd87bfc --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/src/org/etsi/mts/tdl/gen/EcoreGeneratorCustom.java @@ -0,0 +1,339 @@ +package org.etsi.mts.tdl.gen; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.eclipse.emf.codegen.ecore.generator.Generator; +import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory; +import org.eclipse.emf.codegen.ecore.genmodel.GenBase; +import org.eclipse.emf.codegen.ecore.genmodel.GenModel; +import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage; +import org.eclipse.emf.codegen.ecore.genmodel.generator.GenBaseGeneratorAdapter; +import org.eclipse.emf.codegen.ecore.genmodel.generator.GenModelGeneratorAdapter; +import org.eclipse.emf.codegen.merge.java.JControlModel; +import org.eclipse.emf.codegen.util.ImportManager; +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.util.BasicMonitor; +import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.common.util.WrappedException; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.URIConverter; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.mwe.utils.GenModelHelper; +import org.eclipse.emf.mwe2.ecore.CvsIdFilteringGeneratorAdapterFactoryDescriptor; +import org.eclipse.emf.mwe2.runtime.Mandatory; +import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowComponent; +import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowContext; + +import com.google.common.base.Function; + +public class EcoreGeneratorCustom implements IWorkflowComponent { + + private static Logger log = Logger.getLogger(EcoreGeneratorCustom.class); + static { + EcorePackage.eINSTANCE.getEFactoryInstance(); + GenModelPackage.eINSTANCE.getEFactoryInstance(); + } + + private boolean generateModel = true; + private boolean generateEdit = false; + private boolean generateEditor = false; + private boolean generateCustomClasses = false; + + private String lineDelimiter = System.getProperty("line.separator"); + + /** + * @since 2.7 + */ + public String getLineDelimiter() { + return lineDelimiter; + } + + /** + * @since 2.7 + */ + public void setLineDelimiter(String lineDelimiter) { + this.lineDelimiter = lineDelimiter; + } + + protected List srcPaths = new ArrayList(); + private String genModel; + + private ResourceSet resourceSet; + protected Generator generator; + + /** + * @since 2.12 + */ + public void setGenerateModel(boolean generateModel) { + this.generateModel = generateModel; + } + + public void setGenerateEdit(boolean generateEdit) { + this.generateEdit = generateEdit; + } + + public void setGenerateEditor(boolean generateEditor) { + this.generateEditor = generateEditor; + } + + public void setGenerateCustomClasses(boolean generateCustomClasses) { + this.generateCustomClasses = generateCustomClasses; + } + + @Mandatory + public void addSrcPath(String srcPath) { + this.srcPaths.add(srcPath); + } + + @Mandatory + public void setGenModel(String genModel) { + this.genModel = genModel; + } + + public void setResourceSet(ResourceSet resourceSet) { + this.resourceSet = resourceSet; + } + + public void preInvoke() { + getResourceSet().getResource(URI.createURI(genModel), true); + } + + public void postInvoke() { + } + + protected GenModelHelper createGenModelSetup() { + return new GenModelHelper(); + } + + public void invoke(IWorkflowContext ctx) { + ResourceSet resSet = getResourceSet(); + Resource resource = resSet.getResource(URI.createURI(genModel), true); + final GenModel genModel = (GenModel) resource.getContents().get(0); + genModel.setCanGenerate(true); + genModel.reconcile(); + createGenModelSetup().registerGenModel(genModel); + + generator = new Generator() { + @Override + public JControlModel getJControlModel() { + return new JControlModel(){ + @Override + public boolean canMerge() { + return false; + } + }; + } + }; + log.info("generating EMF code for "+this.genModel); + addAdapters(); + + generator.setInput(genModel); + + if (generateModel) { + Diagnostic diagnostic = generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, + new BasicMonitor()); + + if (diagnostic.getSeverity() != Diagnostic.OK) { + log.info(diagnostic); + } + for (Diagnostic c :diagnostic.getChildren()) { + if (c.getException() != null) { + System.err.println(c.getException().getLocalizedMessage()); + c.getException().printStackTrace(); + } + } + } + + if (generateEdit) { + Diagnostic editDiag = generator.generate(genModel, GenBaseGeneratorAdapter.EDIT_PROJECT_TYPE, + new BasicMonitor()); + if (editDiag.getSeverity() != Diagnostic.OK) + log.info(editDiag); + } + + if (generateEditor) { + Diagnostic editorDiag = generator.generate(genModel, GenBaseGeneratorAdapter.EDITOR_PROJECT_TYPE, + new BasicMonitor()); + if (editorDiag.getSeverity() != Diagnostic.OK) + log.info(editorDiag); + } + } + + protected void addAdapters() { + generator.getAdapterFactoryDescriptorRegistry().addDescriptor(GenModelPackage.eNS_URI, + new GeneratorAdapterDescriptor(getTypeMapper(), getLineDelimiter())); + } + + private ResourceSet getResourceSet() { + return resourceSet == null ? new ResourceSetImpl() : resourceSet; + } + + protected Function getTypeMapper() { + return new mapper(); + } + + + protected final class mapper implements Function { + public String apply(String from) { + if (from.startsWith("org.eclipse.emf.ecore")) + return null; + String customClassName = from+"Custom"; + String fromPath = from.replace('.', '/'); + for(String srcPath: srcPaths) { + URI createURI = URI.createURI(srcPath+"/"+fromPath+"Custom.java"); + if (URIConverter.INSTANCE.exists(createURI, null)) { + return customClassName; + } + if (from.endsWith("Impl") && generateCustomClasses) { + generate(from,customClassName,createURI); + return customClassName; + } + } + if (getClass().getClassLoader().getResourceAsStream(fromPath + "Custom.class") != null) { + return customClassName; + } + return null; + } + } + + public void generate(String from,String customClassName, URI path) { + StringBuilder sb =new StringBuilder(); + sb.append(copyright()).append("\n"); + int lastIndexOfDot = customClassName.lastIndexOf('.'); + sb.append("package ").append(customClassName.substring(0, lastIndexOfDot)).append(";\n\n\n"); + sb.append("public class ").append(customClassName.substring(lastIndexOfDot+1)).append(" extends ").append(from).append(" {\n\n"); + sb.append("}\n"); + + try { + OutputStream stream = URIConverter.INSTANCE.createOutputStream(path); + stream.write(sb.toString().getBytes()); + stream.close(); + } catch (IOException e) { + throw new WrappedException(e); + } + } + + protected String copyright() { + return "/*******************************************************************************\n"+ + "* Copyright (c) 2008 - 2010 itemis AG (http://www.itemis.eu) and others.\n"+ + "* This program and the accompanying materials are made available under the\n"+ + "* terms of the Eclipse Public License 2.0 which is available at\n"+ + "* http://www.eclipse.org/legal/epl-2.0.\n"+ + "*\n"+ + "* SPDX-License-Identifier: EPL-2.0\n"+ + "*******************************************************************************/"; + } + + + + /** + * @author Sven Efftinge - Initial contribution and API + */ + protected static class GeneratorAdapterDescriptor extends CvsIdFilteringGeneratorAdapterFactoryDescriptor { + /** + * @author Sebastian Zarnekow - Initial contribution and API + */ + private final class CustomImplAwareGeneratorAdapterFactory extends IdFilteringGenModelGeneratorAdapterFactory { + @Override + public Adapter createGenClassAdapter() { + return new IdFilteringGenClassAdapter(this) { + @Override + protected void createImportManager(String packageName, String className) { + importManager = new ImportManagerHack(packageName, typeMapper); + importManager.addMasterImport(packageName, className); + if (generatingObject != null) + ((GenBase) generatingObject).getGenModel().setImportManager(importManager); + } + }; + } + + @Override + public Adapter createGenEnumAdapter() { + return new IdFilteringGenEnumAdapter(this) { + @Override + protected void createImportManager(String packageName, String className) { + importManager = new ImportManagerHack(packageName, typeMapper); + importManager.addMasterImport(packageName, className); + if (generatingObject != null) + ((GenBase) generatingObject).getGenModel().setImportManager(importManager); + } + }; + } + + @Override + public Adapter createGenModelAdapter() { + if (genModelGeneratorAdapter == null) { + genModelGeneratorAdapter = new GenModelGeneratorAdapter(this) { + @Override + protected void createImportManager(String packageName, String className) { + importManager = new ImportManagerHack(packageName, typeMapper); + importManager.addMasterImport(packageName, className); + if (generatingObject != null) + ((GenBase) generatingObject).getGenModel().setImportManager( + importManager); + } + + }; + } + return genModelGeneratorAdapter; + } + + @Override + public Adapter createGenPackageAdapter() { + return new IdFilteringGenPackageAdapter(this) { + @Override + protected void createImportManager(String packageName, String className) { + importManager = new ImportManagerHack(packageName, typeMapper); + importManager.addMasterImport(packageName, className); + if (generatingObject != null) + ((GenBase) generatingObject).getGenModel().setImportManager(importManager); + } + }; + } + } + + private Function typeMapper; + + protected GeneratorAdapterDescriptor(Function typeMapper) { + this.typeMapper = typeMapper; + } + + public GeneratorAdapterDescriptor(Function typeMapper, String lineDelimiter) { + super(lineDelimiter); + this.typeMapper = typeMapper; + } + + @Override + public GeneratorAdapterFactory createAdapterFactory() { + return new CustomImplAwareGeneratorAdapterFactory(); + } + } + + protected static class ImportManagerHack extends ImportManager { + + private Function typeMapper; + + public ImportManagerHack(String compilationUnitPackage, Function typeMapper) { + super(compilationUnitPackage); + this.typeMapper = typeMapper; + } + + @Override + public String getImportedName(String qualifiedName, boolean autoImport) { + String mapped = typeMapper.apply(qualifiedName); + if (mapped != null) { + log.debug("mapping " + qualifiedName + " to " + mapped); + return super.getImportedName(mapped, autoImport); + } else + return super.getImportedName(qualifiedName, autoImport); + } + } + +} diff --git a/plugins/org.etsi.mts.tdl.model.gen/src/org/etsi/mts/tdl/gen/OCLinEcoreGenerator.java b/plugins/org.etsi.mts.tdl.model.gen/src/org/etsi/mts/tdl/gen/OCLinEcoreGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..e9c66947e342f0f046a5970ae969d0e16990173e --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model.gen/src/org/etsi/mts/tdl/gen/OCLinEcoreGenerator.java @@ -0,0 +1,94 @@ +package org.etsi.mts.tdl.gen; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Paths; + +import org.apache.log4j.Logger; +import org.eclipse.emf.codegen.ecore.generator.Generator; +import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory; +import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage; +import org.eclipse.emf.codegen.ecore.genmodel.generator.GenModelGeneratorAdapterFactory; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.plugin.EcorePlugin; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.URIConverter; +import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowContext; +import org.eclipse.ocl.examples.codegen.oclinecore.OCLinEcoreGeneratorAdapterFactory; +import org.eclipse.ocl.pivot.utilities.OCL; +import org.eclipse.ocl.xtext.oclinecore.OCLinEcoreStandaloneSetup; + +public class OCLinEcoreGenerator extends EcoreGeneratorCustom { + private String projectRoot = ""; + private static Logger log = Logger.getLogger(OCLinEcoreGenerator.class); + + @Override + public void invoke(IWorkflowContext ctx) { + log.info("Running on: "+projectRoot); + //TODO: handle if unresolved? + String codeGenJar = locateContainingJar(Generator.class); + EcorePlugin.ExtensionProcessor.process(null); + //TODO: add others to make sure it runs properly also in Eclipse? -> not clear which and if it helps + //test with base class and with original -> none work directly + //run MWE / XtextCodeGenerator runner to test quickly + URIConverter.URI_MAP.put( + URI.createURI("platform:/plugin/org.eclipse.emf.codegen.ecore/"), + URI.createURI(codeGenJar) + ); + + File projectRoot = new File(getProjectRoot()).getAbsoluteFile(); + + URIConverter.URI_MAP.put( + URI.createURI("platform:/resource/"+projectRoot.getName()+"/"), + URI.createFileURI(projectRoot.getAbsolutePath() + File.separator) + ); + + OCLinEcoreStandaloneSetup.doSetup(); + OCL ocl = OCL.newInstance(); + ResourceSet resourceSet = ocl.getResourceSet(); + setResourceSet(resourceSet); + + GeneratorAdapterFactory.Descriptor.Registry.INSTANCE.addDescriptor( + GenModelPackage.eNS_URI, + GenModelGeneratorAdapterFactory.DESCRIPTOR); // standard EMF codegen + GeneratorAdapterFactory.Descriptor.Registry.INSTANCE.addDescriptor( + GenModelPackage.eNS_URI, + OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR); // OCL→Java compilation + + super.invoke(ctx); + } + + @Override + protected void addAdapters() { +// super.addAdapters(); +// generator.getAdapterFactoryDescriptorRegistry().addDescriptor( +// GenModelPackage.eNS_URI, +// GenModelGeneratorAdapterFactory.DESCRIPTOR); // standard EMF codegen +// generator.getAdapterFactoryDescriptorRegistry().addDescriptor( +// GenModelPackage.eNS_URI, +// OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR); // OCL→Java compilation + } + + + protected String locateContainingJar(Class clazz) { + URL url = clazz.getProtectionDomain().getCodeSource().getLocation(); + try { + return "jar:file:"+Paths.get(url.toURI()).toString()+"!/"; + } catch (URISyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + public String getProjectRoot() { + return projectRoot; + } + + public void setProjectRoot(String projectRoot) { + this.projectRoot = projectRoot; + } + + +} diff --git a/plugins/org.etsi.mts.tdl.model/.classpath b/plugins/org.etsi.mts.tdl.model/.classpath index ad0cecafb26ec831709f3a76542866cbd9a84f17..8f1fa281ed745bc6a312ed1cc15839e37ade75c0 100644 --- a/plugins/org.etsi.mts.tdl.model/.classpath +++ b/plugins/org.etsi.mts.tdl.model/.classpath @@ -2,7 +2,7 @@ - + diff --git a/plugins/org.etsi.mts.tdl.model/.project b/plugins/org.etsi.mts.tdl.model/.project index dc251f152e3f95caede138dc9a5d53ac0458dc84..395bb46a9fa35ec102a710ca303ab1eaa47f282b 100644 --- a/plugins/org.etsi.mts.tdl.model/.project +++ b/plugins/org.etsi.mts.tdl.model/.project @@ -6,18 +6,30 @@ - org.eclipse.xtext.ui.shared.xtextBuilder + org.eclipse.ocl.pivot.ui.oclbuilder + full,incremental, + + disabledExtensions + *,essentialocl + + + disabledPaths + bin/**,target/** + + + enabledExtensions + ecore,ocl,oclinecore,oclstdlib,uml + + + enabledPaths + model/** + - org.eclipse.ui.externaltools.ExternalToolBuilder - full,incremental, + org.eclipse.xtext.ui.shared.xtextBuilder - - LaunchConfigHandle - <project>/.externalToolBuilders/org.eclipse.ocl.pivot.ui.oclbuilder.launch - @@ -45,8 +57,8 @@ org.eclipse.m2e.core.maven2Nature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature - org.eclipse.ocl.pivot.ui.oclnature org.eclipse.xtext.ui.shared.xtextNature + org.eclipse.ocl.pivot.ui.oclnature diff --git a/plugins/org.etsi.mts.tdl.model/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.model/.settings/org.eclipse.jdt.core.prefs index 4a7e0723d6efee0525a636a07706c95bbbe13f88..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.model/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.model/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.model/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.model/META-INF/MANIFEST.MF index b0a68d9dc20ef6d79a6f4108fddbc000e623b414..d9cbcaad15511ce4bfab378c37d84759e8b3d4dd 100644 --- a/plugins/org.etsi.mts.tdl.model/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.model/META-INF/MANIFEST.MF @@ -7,7 +7,7 @@ Bundle-Version: 1.4.0.qualifier Bundle-ClassPath: . Bundle-Vendor: %providerName Bundle-Localization: plugin -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl, org.etsi.mts.tdl.extendedconfigurations, org.etsi.mts.tdl.extendedconfigurations.impl, @@ -31,7 +31,9 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.emf.mwe2.lib;resolution:=optional, org.eclipse.emf.codegen.ecore;resolution:=optional, org.apache.log4j;resolution:=optional, - org.apache.commons.logging;resolution:=optional + org.apache.commons.logging;resolution:=optional, + org.objectweb.asm;resolution:=optional, + org.etsi.mts.tdl.model.gen;resolution:=optional Eclipse-LazyStart: true Bundle-ActivationPolicy: lazy Bundle-Activator: org.etsi.mts.tdl.Activator diff --git a/plugins/org.etsi.mts.tdl.model/model/GenerateTDL.mwe2 b/plugins/org.etsi.mts.tdl.model/model/GenerateTDL.mwe2 index bfa5a1204f994da6f508fdafe10c004cdf3e6c42..4d74f4d3bf0cd34f337913edbcb42737ca9062d8 100644 --- a/plugins/org.etsi.mts.tdl.model/model/GenerateTDL.mwe2 +++ b/plugins/org.etsi.mts.tdl.model/model/GenerateTDL.mwe2 @@ -2,11 +2,11 @@ module org.etsi.mts.tdl.GenerateTDL import org.eclipse.xtext.xtext.generator.* import org.eclipse.xtext.xtext.generator.model.project.* +import org.etsi.mts.tdl.gen.* -var rootPath = "platform:/resource/org.etsi.mts.tdl.model" -//var rootPath = "platform:/resource/" -var rootPaths = "org.etsi.mts.tdl.model" - +var rootPath = "" +var projectName = "org.etsi.mts.tdl.model" +var srcGen = "src-gen" //this does not seem to matter... -> only for cleaning Workflow { bean = org.eclipse.emf.mwe.utils.StandaloneSetup { @@ -15,38 +15,40 @@ Workflow { } component = org.eclipse.emf.mwe.utils.DirectoryCleaner { - directory ="src-gen" - } + directory ="${srcGen}" + } - component = org.eclipse.emf.mwe2.ecore.EcoreGenerator { + //TODO: this only works in maven, starting directly it generates mostly empty files +// component = org.eclipse.emf.mwe2.ecore.EcoreGenerator { + component = org.etsi.mts.tdl.gen.OCLinEcoreGenerator { generateCustomClasses = false generateModel = true generateEdit = false generateEditor = false - genModel = "platform:/resource/${rootPaths}/model/tdl.genmodel" - srcPath = "platform:/resource/${rootPaths}/src-gen" -// genModel = "../plugins/${rootPaths}/model/tdl.genmodel" + projectRoot = "${rootPath}" + genModel = "platform:/resource/${projectName}/model/tdl.genmodel" + srcPath = "platform:/resource/${projectName}/${srcGen}" } - component = org.eclipse.emf.mwe2.ecore.EcoreGenerator { +// component = org.eclipse.emf.mwe2.ecore.EcoreGenerator { + component = org.etsi.mts.tdl.gen.OCLinEcoreGenerator { generateCustomClasses = false generateModel = true generateEdit = false generateEditor = false - genModel = "platform:/resource/${rootPaths}/model/structured.genmodel" - srcPath = "platform:/resource/${rootPaths}/src-gen" + projectRoot = "${rootPath}" + genModel = "platform:/resource/${projectName}/model/structured.genmodel" + srcPath = "platform:/resource/${projectName}/${srcGen}" } - - component = org.eclipse.emf.mwe2.ecore.EcoreGenerator { +// component = org.eclipse.emf.mwe2.ecore.EcoreGenerator { + component = org.etsi.mts.tdl.gen.OCLinEcoreGenerator { generateCustomClasses = false generateModel = true generateEdit = false generateEditor = false - genModel = "platform:/resource/${rootPaths}/model/configurations.genmodel" - srcPath = "platform:/resource/${rootPaths}/src-gen" + projectRoot = "${rootPath}" + genModel = "platform:/resource/${projectName}/model/configurations.genmodel" + srcPath = "platform:/resource/${projectName}/${srcGen}" } - } -//TODO: move to separate project? -//TODO: repeat for structured and configurations diff --git a/plugins/org.etsi.mts.tdl.model/model/configurations.genmodel b/plugins/org.etsi.mts.tdl.model/model/configurations.genmodel index 3a5aac0a943718b430943ca6c66cefc2121bf9bd..ec38d7499907a43c86726f4bce89b0963d607c39 100644 --- a/plugins/org.etsi.mts.tdl.model/model/configurations.genmodel +++ b/plugins/org.etsi.mts.tdl.model/model/configurations.genmodel @@ -1,9 +1,12 @@ + +
+ configurations.ecore diff --git a/plugins/org.etsi.mts.tdl.model/model/structured.ecore b/plugins/org.etsi.mts.tdl.model/model/structured.ecore index f9179c2ce5a3c64b24d14e2c0979a0b931e7dc51..ffb305266137bf82bd413a24dc76c57baf1ef487 100644 --- a/plugins/org.etsi.mts.tdl.model/model/structured.ecore +++ b/plugins/org.etsi.mts.tdl.model/model/structured.ecore @@ -3,8 +3,14 @@ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="structuredobjectives" nsURI="http://www.etsi.org/spec/TDL/1.3.1/structured" nsPrefix="structured"> +
+ +
+
+
+ @@ -13,20 +19,20 @@ -
+
-
+
-
+
@@ -93,7 +99,7 @@ + eType="ecore:EClass tdl.ecore#//DataUse" containment="true"/> + +
+ structured.ecore diff --git a/plugins/org.etsi.mts.tdl.model/model/tdl-constraints.ocl b/plugins/org.etsi.mts.tdl.model/model/tdl-constraints.ocl index 5e7ac326cc698212e151994d4b05e37352a3a1f2..1d2ec31f7a98e88b5a9a498e9fc2b2f5abcb1ff7 100644 --- a/plugins/org.etsi.mts.tdl.model/model/tdl-constraints.ocl +++ b/plugins/org.etsi.mts.tdl.model/model/tdl-constraints.ocl @@ -2,6 +2,25 @@ import 'http://www.etsi.org/spec/TDL/1.4.1' package tdl +context Element + def: error(constraint : Boolean) : Boolean = + if constraint then true else null endif + def: warning(constraint : Boolean) : Boolean = + if constraint then true else false endif + def: traceName() : String = + if self.oclIsKindOf(NamedElement) then + '['+self.oclType().name+' : '+self.name+']' + else + '['+self.oclType().name+']' + endif + + def: trace() : String = + Sequence{self}->closure(e | e.container()) + ->collect(e|e.traceName()) + ->reverse() + ->iterate(e; r : String = ' ' | r + ' -> ' +e) + + context NamedElement -- Mandatory name inv MandatoryName ('A \'NamedElement\' shall have the \'name\' property set and the \'name\' shall be not an empty String.' + self.toString()): @@ -65,6 +84,9 @@ context Extension inv Extension ('The element containing an \'Extension\' and the element in the \'extending\' property shall have the same meta-class.' + self.toString()): self.container().oclType() = self.extending.oclType() + -- No recursive extension + inv NoRecursiveExtension ('The element containing an \'Extension\' shall not extend itself directly or indirectly.' + self.toString()): + Set{self}->closure(e | e.transitiveExtending())->collect(e|e.extending)->excludes(self.container()) @@ -203,7 +225,7 @@ context StructuredDataInstance context MemberAssignment -- Type of a 'memberSpec' shall conform to the type of the 'member' inv MatchingMemberDataType ('The \'DataType\' of the \'DataUse\' of \'memberSpec\' shall conform to the \'DataType\' of the \'Member\' of the \'MemberAssignment\'.' + self.toString()): - self.memberSpec.resolveDataType().conformsTo(self.member.dataType) + error(self.memberSpec.resolveDataType().conformsTo(self.member.dataType)) -- Restricted use of 'OmitValue' for optional 'Member's only @@ -271,21 +293,20 @@ context DataUse -- Members in 'reduction' list inv ReductionMembers ('The \'Member\' referenced by the \'MemberReference\' at index i of a \'reduction\' shall be contained in or inherited by the \'StructuredDataType\' of the \'Member\' referenced by the \'MemberReference\' at index (i - 1) of that \'reduction\' or the \'StructuredDataType\' of this \'DataUse\' if the \'MemberReference\' is the first element of the \'reduction\'.' + self.toString()): - self.reduction->isEmpty() - or self.reduction->reject(r | self.reduction->indexOf(r) = 1) - ->iterate(r; acc = Sequence{Sequence{self.resolveBaseDataType(), self.reduction->at(1)}} - | acc->including(Sequence{self.reduction->at(self.reduction->indexOf(r) - 1)->asSequence() - ->reject(r|r.member.oclIsUndefined()).member.dataType->including(self.resolveBaseDataType())->at(1), r - })) - ->reject(tr | tr->at(1).oclIsUndefined() or tr->at(2).oclAsType(MemberReference).member.oclIsUndefined()) - ->iterate(tr; acc = Sequence{} | acc->including(Sequence{tr->at(1)->asSequence() - ->select(t|t.oclIsKindOf(CollectionDataType)).oclAsType(CollectionDataType).itemType->including(tr->at(1))->at(1), tr->at(2) - })) - ->forAll(tr | tr->at(1).oclAsType(StructuredDataType).allMembers()->includes(tr->at(2).oclAsType(MemberReference).member)) - + self.reduction->forAll(mr | mr.member.oclIsUndefined() + or self.reduction->indexOf(mr) = 1 + or (not self.reduction->at(self.reduction->indexOf(mr)-1).member.oclIsUndefined() + and (let dataType = self.reduction->at(self.reduction->indexOf(mr)-1).member.dataType in + ((dataType.oclIsKindOf(StructuredDataType) + and dataType.oclAsType(StructuredDataType).allMembers()->includes(mr.member)) + or (dataType.oclIsKindOf(CollectionDataType) + and dataType.oclAsType(CollectionDataType).itemType.oclIsKindOf(StructuredDataType) + and dataType.oclAsType(CollectionDataType).itemType.oclAsType(StructuredDataType).allMembers()->includes(mr.member))))) + or (self.reduction->at(self.reduction->indexOf(mr)-1).member.oclIsUndefined()) + ) -- Collection index of first 'reduction' - inv ReductionMembers ('If the \'member\' is not specified for the first element of the \'reduction\' then the type of this \'DataUse\' shall be \'CollectionDataType\'.' + self.toString()): + inv ReductionMembersCollection ('If the \'member\' is not specified for the first element of the \'reduction\' then the type of this \'DataUse\' shall be \'CollectionDataType\'.' + self.toString()): self.reduction->isEmpty() or not self.reduction->at(1).member.oclIsUndefined() or self. resolveBaseDataType().oclIsKindOf(CollectionDataType) @@ -294,6 +315,10 @@ context DataUse context ParameterBinding + -- Matching data type + inv ParameterBindingTypes ('The provided \'DataUse\' shall conform to the \'DataType\' of the referenced \'Parameter\'.' + self.trace()): + error(self.dataUse.resolveDataType().conformsTo(self.resolveParameterType())) + -- Members in 'reduction' list of parameter inv ReductionMembers ('The \'Member\' referenced by the \'MemberReference\' at index i of a \'reduction\' shall be contained in or inherited by the \'StructuredDataType\' of the \'Member\' referenced by the \'MemberReference\' at index (i - 1) of that \'reduction\' or the \'StructuredDataType\' of the \'parameter\' if the \'MemberReference\' is the first element of the \'reduction\'.' + self.toString()): self.reduction->isEmpty() @@ -310,7 +335,7 @@ context ParameterBinding -- Collection index of first 'reduction' of parameter - inv ReductionMembers ('If the \'member\' is not specified for the first element of the \'reduction\' then the type of the \'parameter\' shall be \'CollectionDataType\'.' + self.toString()): + inv ReductionMembersCollection ('If the \'member\' is not specified for the first element of the \'reduction\' then the type of the \'parameter\' shall be \'CollectionDataType\'.' + self.toString()): self.reduction->isEmpty() or not self.reduction->at(1).member.oclIsUndefined() or self.parameter.dataType.oclIsKindOf(CollectionDataType) @@ -427,10 +452,13 @@ context DataElementUse -- 'DataElement' reference or non-empty 'argument' or non-empty 'item' inv DataInstanceOrArgumentsOrItemsInDataElementUse ('If a \'dataElement\' is not specified, or if the \'dataElement\' is resolved to a \'StructuredDataType\' or a \'CollectionDataType\', either a non-empty \'argument\' set or a non-empty \'item\' set shall be specified.' + self.toString()): not (self.dataElement.oclIsUndefined() and self.argument->isEmpty() and self.item->isEmpty()) - and (self.dataElement.oclIsKindOf(StructuredDataInstance) + or (self.dataElement.oclIsKindOf(StructuredDataInstance) or not (self.resolveDataType().oclIsKindOf(StructuredDataType) - and self.argument->isEmpty())) - and (self.dataElement.oclIsKindOf(CollectionDataInstance) + and self.argument->isEmpty()) + or (self.resolveDataType().oclIsKindOf(StructuredDataType) + and self.dataElement.oclIsKindOf(CollectionDataInstance) + )) + or (self.dataElement.oclIsKindOf(CollectionDataInstance) or not (self.resolveDataType().oclIsKindOf(CollectionDataType) and self.item->isEmpty())) @@ -609,11 +637,10 @@ context TestConfiguration -- At most one connection between any two 'GateInstance'/'ComponentInstance' pairs inv UniqueConnections ('Given the set of \'Connection\'s contained in a \'TestConfiguration\'. There shall be no two \'Connection\'s containing \'GateReference\'s that in turn refer to identical pairs of \'GateInstance\'/\'ComponentInstance\'.' + self.toString()): - self.connection->forAll(c1 | self.connection->one(c2 | - not c1.endPoint->reject(ep1 | not c2.endPoint->exists(ep2 | - ep1.component = ep2.component and ep1.gate = ep2.gate - ))->isEmpty())) - + self.connection->forAll(c1 | + self.connection->one(c2 | c1.endPoint->reject(ep1 | c2.endPoint->exists(ep2 | + (ep1.component = ep2.component and ep1.gate = ep2.gate) + ))->isEmpty())) @@ -630,10 +657,10 @@ context Block -- Guard for each participating tester in locally ordered test descriptions - inv GuardsForParticipatingComponents ('If the \'Block\' is contained in a locally ordered \'TestDescription\' then a guard shall be specified for every participating \'ComponentInstance\' in the associated \'TestConfiguration\' that has the role \'Tester\' or there shall be no guards at all. ' + self.toString()): + inv GuardsForParticipatingComponents ('If the \'Block\' is contained in a locally ordered \'TestDescription\' then exactly one guard shall be specified for every participating \'ComponentInstance\' in the associated \'TestConfiguration\' that has the role \'Tester\' or there shall be no guards at all. ' + self.toString()): self.guard->size() = 0 or self.getParticipatingComponents()->reject(c | c.role = ComponentInstanceRole::SUT) - ->forAll(c | self.guard->exists(ex | ex.componentInstance = c)) + ->forAll(c | self.guard->one(ex | ex.componentInstance = c)) or not self.getParentTestDescription().isLocallyOrdered @@ -738,9 +765,9 @@ context AlternativeBehaviour inv AlternativeBlocksComponent ('If the containing \'TestDescription\' is locally ordered then all \'Block\'s shall start with a tester-input event of the same \'ComponentInstance\'. ' + self.toString()): let initial = self.block.behaviour->first() in Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) ->size() = 1 or not self.getParentTestDescription().isLocallyOrdered @@ -748,9 +775,9 @@ context AlternativeBehaviour inv AlternativeBehaviourParticipation ('If the \'AlternativeBehaviour\' is contained in a locally ordered \'TestDescription\' then no other tester \'ComponentInstance\' shall participate in any block than the target of the first tester-input event and \'ComponentInstance\'s participating in blocks of contained \'OptionalBehaviour\'s. ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance), + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance), nonOptionalBlocks = self.block->closure( b | b.behaviour->reject(oclIsKindOf(OptionalBehaviour)) ->select(oclIsKindOf(SingleCombinedBehaviour)).oclAsType(SingleCombinedBehaviour).block @@ -767,11 +794,13 @@ context AlternativeBehaviour inv OptionalAlternativeBehaviour ('A block of an \'AlternativeBehaviour\' if the containing \'TestDescription\' is locally ordered, shall only contain \'OptionalBehaviour\'(s) whose source \'ComponentInstance\' is the same as the target of the first tester-input event of that \'Block\'. ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) in - self.block.behaviour->select(oclIsKindOf(OptionalBehaviour)) .oclAsType(OptionalBehaviour).block + self.block.behaviour->select(oclIsKindOf(OptionalBehaviour))->isEmpty() + or + self.block.behaviour->select(oclIsKindOf(OptionalBehaviour)) .oclAsType(OptionalBehaviour).block.behaviour ->first().oclAsType(Interaction).sourceGate.component->forAll(c | targetComponent->includes(c)) or not self.getParentTestDescription().isLocallyOrdered @@ -781,7 +810,7 @@ context AlternativeBehaviour context ConditionalBehaviour -- Guard for 'ConditionalBehaviour' with single block inv ConditionalFirstGuard ('If there is only one \'Block\' specified, it shall have a \'guard\'.' + self.toString()): - self.block->size() > 1 or self.block->first().guard->size() > 1 + self.block->size() > 1 or self.block->first().guard->size() > 0 -- Possible else block for 'ConditionalBehaviour' with multiple blocks @@ -816,9 +845,9 @@ context ExceptionalBehaviour inv ExceptionalGuardedandTargetComponent ('If the containing \'TestDescription\' is locally ordered and guardedComponent is specified then the \'Block\'s shall start with tester-input event of the same \'ComponentInstance\' as specified in guardedComponent. ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) in guardedComponent->includesAll(targetComponent) or not self.getParentTestDescription().isLocallyOrdered @@ -828,9 +857,9 @@ context ExceptionalBehaviour inv ExceptionalBehaviourParticipation ('If the \'ExceptionalBehaviour\' is contained in a locally ordered \'TestDescription\' then no other tester \'ComponentInstance\' shall participate in any block than the target of the first tester-input event and \'ComponentInstance\'s participating in blocks of contained \'OptionalBehaviour\'s . ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance), + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance), nonOptionalBlocks = self.block->closure( b | b.behaviour->reject(oclIsKindOf(OptionalBehaviour)) ->select(oclIsKindOf(SingleCombinedBehaviour)).oclAsType(SingleCombinedBehaviour).block @@ -847,12 +876,12 @@ context ExceptionalBehaviour inv OptionalExceptionalBehaviour ('A block of an \'ExceptionalBehaviour\' if the containing \'TestDescription\' is locally ordered, shall only contain \'OptionalBehaviour\'(s) whose source \'ComponentInstance\' is the same as the target of the first tester-input event of that \'Block\'. ' + self.toString()): let initial = self.block.behaviour->first(), targetComponent = Set{} - ->including(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) - ->including(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) - -> including(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) + ->includingAll(initial->select(oclIsKindOf(Interaction)).oclAsType(Interaction).target.targetGate.component) + ->includingAll(initial->select(oclIsKindOf(Quiescence)).oclAsType(Quiescence).componentInstance) + -> includingAll(initial->select(oclIsKindOf(TimeOut)).oclAsType(TimeOut).componentInstance) in - self.block.behaviour->select(oclIsKindOf(OptionalBehaviour)).oclAsType(OptionalBehaviour).block - ->first().oclAsType(Interaction).sourceGate.component->forAll(c | targetComponent->includes(c)) + self.block.behaviour->select(oclIsKindOf(OptionalBehaviour)).oclAsType(OptionalBehaviour)->forAll(op | op.block.behaviour->asSequence() + ->first().oclAsType(Interaction).sourceGate.component->forAll(c | targetComponent->includes(c))) or not self.getParentTestDescription().isLocallyOrdered @@ -923,8 +952,8 @@ context Interaction inv ConnectedInteractionGates ('The \'GateReference\'s that act as source or target(s) of an \'Interaction\' shall be interconnected by a \'Connection\' which is contained in the \'TestConfiguration\' referenced by the \'TestDescription\' containing the \'Interaction\'.' + self.toString()): self.target->forAll(t | self.getParentTestDescription().testConfiguration.connection->exists(c | - not c.endPoint->reject(ep | - (ep.component = self.sourceGate.component and ep.gate = self.sourceGate.component) or + c.endPoint->reject(ep | + (ep.component = self.sourceGate.component and ep.gate = self.sourceGate.gate) or (ep.component = t.targetGate.component and ep.gate = t.targetGate.gate) )->isEmpty())) @@ -982,7 +1011,7 @@ context ProcedureCall -- Each call has a reply inv ProcedureCallHasReply ('For every \'ProcedureCall\' with empty \'replyTo\' there shall be one or more \'ProcedureCall\'s that have this \'ProcedureCall\' as \'replyTo\'. ' + self.toString()): - ProcedureCall.allInstances()->exists(pc | pc.replyTo = self) + self.replyTo.oclIsUndefined() implies ProcedureCall.allInstances()->exists(pc | pc.replyTo = self) -- Call and reply within the same 'TestDescription' @@ -1014,8 +1043,11 @@ context ProcedureCall and (not b.oclAsType(TestDescriptionReference).componentInstanceBinding->isEmpty() and not b.oclAsType(TestDescriptionReference).componentInstanceBinding .actualComponent->includes(self))), - following = affectingBehaviours ->at(affectingBehaviours->indexOf(self) + 1) - in (following.oclIsKindOf(ProcedureCall) and following.oclAsType(ProcedureCall).replyTo = self) + selfIndex = affectingBehaviours->indexOf(self), + following = affectingBehaviours ->reject(b | affectingBehaviours->indexOf(b) <= selfIndex)->first() + in following.oclIsUndefined() + or not self.replyTo.oclIsUndefined() + or (following.oclIsKindOf(ProcedureCall) and following.oclAsType(ProcedureCall).replyTo = self) or (following.oclIsKindOf(AlternativeBehaviour) and following.oclAsType(AlternativeBehaviour).block->exists( b | b.behaviour->first().oclIsKindOf(ProcedureCall) diff --git a/plugins/org.etsi.mts.tdl.model/model/tdl-structured-constraints.ocl b/plugins/org.etsi.mts.tdl.model/model/tdl-structured-constraints.ocl index dee88616144d5979b59a2c458f618fb1471db0c9..fc50ce382742b8b851d7a6c4cde09a220f9a4844 100644 --- a/plugins/org.etsi.mts.tdl.model/model/tdl-structured-constraints.ocl +++ b/plugins/org.etsi.mts.tdl.model/model/tdl-structured-constraints.ocl @@ -8,7 +8,7 @@ context PICSReference inv MultiplePICS ('A \'Comment\' with body containing an \'and\' or \'or\' shall be attached to the \'PICSReference\' as a Boolean operand if there are two or more \'PICSReference\'s and it is not the first \'PICSReference\'.' + self.toString()): self.getTestObjective().picsReference->size() < 2 or self.getTestObjective().picsReference->forAll(p | - self.getTestObjective().picsReference->at(0) = p + self.getTestObjective().picsReference->at(1) = p or (not p.comment->isEmpty() and (p.comment->first()._'body' = 'and' or p.comment->first()._'body' = 'or'))) diff --git a/plugins/org.etsi.mts.tdl.model/model/tdl.ecore b/plugins/org.etsi.mts.tdl.model/model/tdl.ecore index ccb0a6359658b41da02e971592b1f254571a9892..d6b34164262912c7a6674ac289a7d18a62a41e7a 100644 --- a/plugins/org.etsi.mts.tdl.model/model/tdl.ecore +++ b/plugins/org.etsi.mts.tdl.model/model/tdl.ecore @@ -133,7 +133,7 @@ -
+
@@ -146,7 +146,7 @@ -
+
@@ -154,7 +154,7 @@ -
+
@@ -194,7 +194,7 @@ -
+
@@ -215,7 +215,7 @@ -
+
-
+
@@ -289,7 +289,7 @@ -
+
@@ -297,7 +297,7 @@ -
+
@@ -318,7 +318,7 @@ -
+
@@ -781,7 +781,7 @@ -
+
@@ -791,7 +791,7 @@ -
+
diff --git a/plugins/org.etsi.mts.tdl.model/model/tdl.genmodel b/plugins/org.etsi.mts.tdl.model/model/tdl.genmodel index 55738719583b82160268f1ccd4cefbddacec254c..55d2a3f006be32a4f04b5aaa3ade48ae9c08d8d2 100644 --- a/plugins/org.etsi.mts.tdl.model/model/tdl.genmodel +++ b/plugins/org.etsi.mts.tdl.model/model/tdl.genmodel @@ -1,9 +1,12 @@ + +
+ configurations.ecore structured.ecore tdl.ecore diff --git a/plugins/org.etsi.mts.tdl.model/plugin.xml b/plugins/org.etsi.mts.tdl.model/plugin.xml index 33b8dd266add85dadceb7c6d23f407019eee0e90..21dee5eae96d4e659c0437c95466c4f740a676d7 100644 --- a/plugins/org.etsi.mts.tdl.model/plugin.xml +++ b/plugins/org.etsi.mts.tdl.model/plugin.xml @@ -21,9 +21,9 @@ - + @@ -46,4 +46,12 @@ + + diff --git a/plugins/org.etsi.mts.tdl.model/pom.xml b/plugins/org.etsi.mts.tdl.model/pom.xml index 5d39e975aacc395f2ace284da324b497cb5e11a1..7f36a4da72d7d3d662658f96e63639decdd04c48 100644 --- a/plugins/org.etsi.mts.tdl.model/pom.xml +++ b/plugins/org.etsi.mts.tdl.model/pom.xml @@ -31,7 +31,7 @@ /${project.basedir}/model/GenerateTDL.mwe2 -p - rootPath=/${project.basedir}/.. + rootPath=${project.basedir} compile true diff --git a/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/Activator.java b/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/Activator.java index 32f03943998cddffeb63912135e2860a062be217..a7aa0c1c530d146b61dbfc491f868b0df20f872a 100644 --- a/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/Activator.java +++ b/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/Activator.java @@ -1,29 +1,5 @@ package org.etsi.mts.tdl; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.emf.common.util.DiagnosticChain; -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EValidator; -import org.eclipse.emf.ecore.resource.Resource.Diagnostic; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; -import org.eclipse.ocl.pivot.resource.CSResource; -import org.eclipse.ocl.pivot.utilities.PivotUtil; -import org.eclipse.ocl.xtext.completeocl.validation.CompleteOCLEObjectValidator; import org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage; import org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage; import org.osgi.framework.BundleActivator; @@ -36,60 +12,17 @@ public class Activator implements BundleActivator { // registerValidator("model/tdl-structured-constraints.ocl", StructuredObjectivesPackage.eINSTANCE, context); // registerValidator("model/tdl-configurations-constraints.ocl", ExtendedConfigurationsPackage.eINSTANCE, context); - registerValidator("model/tdl-constraints.ocl", tdlPackage.eINSTANCE, context); - - } - - void registerValidator(String path, EPackage ePakcage, BundleContext context) { - - Path oclPath = new Path(path); - URL oclURL = FileLocator.find(context.getBundle(), oclPath); + Validator.registerValidator("model/tdl-constraints.ocl", tdlPackage.eINSTANCE, context); + Validator.registerValidator("model/tdl-structured-constraints.ocl", StructuredObjectivesPackage.eINSTANCE, context); + Validator.registerValidator("model/tdl-configurations-constraints.ocl", ExtendedConfigurationsPackage.eINSTANCE, context); - URI oclURI; - try { - oclURI = URI.createURI(oclURL.toURI().toString()); - CompleteOCLEObjectValidator validator = new CompleteOCLEObjectValidator(ePakcage, oclURI) { - @Override - public boolean initialize(@NonNull EnvironmentFactoryInternal environmentFactory) { - boolean success = super.initialize(environmentFactory); - if (success) { - // This should happen in super.initialize(..) but under certain conditions it returns early - ResourceSet resourceSet = environmentFactory.getResourceSet(); - CSResource xtextResource = (CSResource) resourceSet.getResource(oclURI, true); - EList errors = xtextResource.getErrors(); - assert errors != null; - String message = PivotUtil.formatResourceDiagnostics(errors, "", "\n"); - if (message != null) { - System.err.println("Failed to load '" + oclURI + message); - return false; - } - } - return success; - } - @Override - protected boolean validatePivot(@NonNull EClassifier eClassifier, @Nullable Object object, - @Nullable DiagnosticChain diagnostics, Map validationContext) { - // Don't validate derived files - if (object instanceof EObject) { - URI uri = ((EObject) object).eResource().getURI(); - IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true))); - if (file != null && file.isDerived()) - return true; - } - return super.validatePivot(eClassifier, object, diagnostics, validationContext); - } - }; - EValidator.Registry.INSTANCE.put(tdlPackage.eINSTANCE, validator); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } } @Override public void stop(BundleContext context) throws Exception { - EValidator.Registry.INSTANCE.remove(StructuredObjectivesPackage.eINSTANCE); - EValidator.Registry.INSTANCE.remove(ExtendedConfigurationsPackage.eINSTANCE); - EValidator.Registry.INSTANCE.remove(tdlPackage.eINSTANCE); + Validator.removeValidator(tdlPackage.eINSTANCE); + Validator.removeValidator(StructuredObjectivesPackage.eINSTANCE); + Validator.removeValidator(ExtendedConfigurationsPackage.eINSTANCE); } } diff --git a/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/Validator.java b/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/Validator.java new file mode 100644 index 0000000000000000000000000000000000000000..fb259db9a20ed7b27bb6dfe5f1370b70987f2e02 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/Validator.java @@ -0,0 +1,180 @@ +package org.etsi.mts.tdl; + +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.emf.common.util.BasicDiagnostic; +import org.eclipse.emf.common.util.DiagnosticChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.Resource.Diagnostic; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; +import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal; +import org.eclipse.ocl.pivot.resource.CSResource; +import org.eclipse.ocl.pivot.utilities.PivotUtil; +import org.eclipse.ocl.pivot.validation.ValidationRegistryAdapter; +import org.eclipse.ocl.xtext.completeocl.validation.CompleteOCLEObjectValidator; +import org.eclipse.xtext.validation.EValidatorRegistrar; +import org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage; +import org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage; +import org.osgi.framework.BundleContext; + +public class Validator { + static CompleteOCLEObjectValidator validator; + public static void reload() { + Validator.removeValidator(tdlPackage.eINSTANCE); + Validator.removeValidator(StructuredObjectivesPackage.eINSTANCE); + Validator.removeValidator(ExtendedConfigurationsPackage.eINSTANCE); + validator = null; + Validator.registerValidator("model/tdl-constraints.ocl", tdlPackage.eINSTANCE); + Validator.registerValidator("model/tdl-structured-constraints.ocl", StructuredObjectivesPackage.eINSTANCE); + Validator.registerValidator("model/tdl-configurations-constraints.ocl", ExtendedConfigurationsPackage.eINSTANCE); + org.eclipse.ocl.pivot.model.OCLstdlib.install(); //needed? move to create? + } + + public static void registerValidator(String path, EValidatorRegistrar registrar, BundleContext context) { + tdlPackage ePackage = tdlPackage.eINSTANCE; + Path oclPath = new Path(path); + URL oclURL = FileLocator.find(context.getBundle(), oclPath); + URI oclURI; + try { + oclURI = URI.createURI(oclURL.toURI().toString()); + registrar.register(ePackage, new CompleteOCLEObjectValidator(ePackage, oclURI)); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + public static void registerValidator(String path, EPackage ePackage, ResourceSet rs, BundleContext context){ + Path oclPath = new Path(path); + URL oclURL = FileLocator.find(context.getBundle(), oclPath); + + URI oclURI; + try { + oclURI = URI.createURI(oclURL.toURI().toString()); + CompleteOCLEObjectValidator validator = createValidator(ePackage, oclURI); + ValidationRegistryAdapter.getAdapter(rs).put(ePackage, validator); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + public static void removeValidator(EPackage ePackage, ResourceSet rs){ + ValidationRegistryAdapter.getAdapter(rs).remove(ePackage); + } + + public static void removeValidator(EPackage ePackage){ + EValidator.Registry.INSTANCE.remove(ePackage); + validator = null; + } + + + public static void registerValidator(String path, EPackage ePackage, BundleContext context) { + Path oclPath = new Path(path); + URL oclURL = FileLocator.find(context.getBundle(), oclPath); + + URI oclURI; + try { + oclURI = URI.createURI(oclURL.toURI().toString()); + CompleteOCLEObjectValidator validator = createValidator(ePackage, oclURI); + + EValidator.Registry.INSTANCE.put(ePackage, validator); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + public static void registerValidator(String path, EPackage ePackage) { + URI uri = URI.createURI("platform:/plugin/org.etsi.mts.tdl.model/"+path); + CompleteOCLEObjectValidator validator = Validator.createValidator(ePackage, uri); + EValidator.Registry.INSTANCE.put(ePackage, validator); + } + + public static CompleteOCLEObjectValidator createValidator(EPackage ePakcage, URI oclURI) { + if (validator != null) { +// return validator; + } + validator = new CompleteOCLEObjectValidator(ePakcage, oclURI) { + private boolean initialised = false; + private EnvironmentFactoryInternal environmentFactory; + private ResourceSet resourceSet; + private CSResource xtextResource; + @Override + public boolean initialize(@NonNull EnvironmentFactoryInternal environmentFactory) { + System.out.println("Init.."); + boolean success = super.initialize(environmentFactory); + if (success) { +// resourceSet = environmentFactory.getResourceSet(); + resourceSet = environmentFactory.getMetamodelManager().getASResourceSet(); + xtextResource = (CSResource) resourceSet.getResource(oclURI, true); + EList errors = xtextResource.getErrors(); + assert errors != null; + String message = PivotUtil.formatResourceDiagnostics(errors, "", "\n"); + if (message != null) { + System.err.println("Failed to load '" + oclURI + message); + return false; + } + initialised = true; + } + return success; + } + @Override + protected boolean validatePivot(@NonNull EClassifier eClassifier, @Nullable Object object, + @Nullable DiagnosticChain diagnostics, Map validationContext) { + // Don't validate derived files + if (object instanceof EObject) { + URI uri = ((EObject) object).eResource().getURI(); + if (uri.isPlatform()) { + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true))); + if (file != null && file.isDerived()) + return true; + } + } +// boolean validation = super.validatePivot(eClassifier, object, diagnostics, validationContext); + //copied from from super, init only once and retain environment factory + if (!initialised) { + EObject eObject = (EObject) object; + ValidationRegistryAdapter adapter = ValidationRegistryAdapter.getAdapter(eObject.eResource().getResourceSet()); + environmentFactory = PivotUtilInternal.getEnvironmentFactory(object); + initialize(environmentFactory); + adapter.put(ePackage, this); + } + ResourceSet resourceSet = getResourceSet(eClassifier, object, diagnostics); + if (resourceSet != null) { + try { + boolean allOk = validate(environmentFactory, eClassifier, object, complementingModels, diagnostics, validationContext); + return allOk || (diagnostics != null); + } catch (Exception e) { + //Try to reload + System.out.println("ERROR: "+e.getLocalizedMessage()); + initialised = false; + environmentFactory = PivotUtilInternal.getEnvironmentFactory(object); + initialize(environmentFactory); + EObject eObject = (EObject) object; + ValidationRegistryAdapter adapter = ValidationRegistryAdapter.getAdapter(eObject.eResource().getResourceSet()); + adapter.put(ePackage, this); + } + } + return true; + + } + }; + return validator; + } + +} diff --git a/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/XtextCodeGenerator.java b/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/XtextCodeGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..a783ef55a111aa672a4c899f4a01a5296eb4c63f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.model/src/org/etsi/mts/tdl/XtextCodeGenerator.java @@ -0,0 +1,12 @@ +package org.etsi.mts.tdl; +import org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher; + +public class XtextCodeGenerator { + public static void main(String[] args) { + // For quick testing and debugging, otherwise has the same problem as the MWE - running directly produces mostly empty files + Mwe2Launcher.main(new String[] { + "model/GenerateTDL.mwe2", + "-p", "rootPath=../" + }); + } +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.openapi.generator.ui/.classpath b/plugins/org.etsi.mts.tdl.openapi.generator.ui/.classpath index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.openapi.generator.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.openapi.generator.ui/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.openapi.generator.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.openapi.generator.ui/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.openapi.generator.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.openapi.generator.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl.next/.classpath b/plugins/org.etsi.mts.tdl.openapi2tdl.next/.classpath index 685a6999c9acba0d0158b0929d7a4d384644452e..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.openapi2tdl.next/.classpath +++ b/plugins/org.etsi.mts.tdl.openapi2tdl.next/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl.next/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.openapi2tdl.next/.settings/org.eclipse.jdt.core.prefs index c9545f06a4120d5b4a1228fb19f67a1171bc0f5b..23fa13b170502d5a7f7a0549188dbc454a7cf0c8 100644 --- a/plugins/org.etsi.mts.tdl.openapi2tdl.next/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.openapi2tdl.next/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl.next/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.openapi2tdl.next/META-INF/MANIFEST.MF index 08da303baf9af736775a8c06505d8685b1c80df9..d3ab897b2f512c95fee9bd8f1cc9582b78a43494 100644 --- a/plugins/org.etsi.mts.tdl.openapi2tdl.next/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.openapi2tdl.next/META-INF/MANIFEST.MF @@ -1,14 +1,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: OpenAPI to TDL Translator (Next) +Bundle-Name: OpenAPI to TDL Translator Bundle-SymbolicName: org.etsi.mts.tdl.openapi2tdl.next;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Vendor: European Telecommunications Standards Institute (ETSI) Automatic-Module-Name: org.etsi.mts.tdl.openapi2tdl.next +Bundle-Activator: org.etsi.mts.tdl.openapi2tdl.next.Activator Require-Bundle: org.etsi.mts.tdl.model, org.etsi.mts.tdl.common, org.etsi.mts.tdl.extras.openapi.generator.wrapper, - org.etsi.mts.tdl.helper, org.eclipse.ui;resolution:=optional, org.eclipse.core.resources;resolution:=optional, org.eclipse.core.runtime;bundle-version="3.26.100";resolution:=optional diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/Activator.java b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/Activator.java new file mode 100644 index 0000000000000000000000000000000000000000..d05f3508d4c6a10108b3b74350059e291395b12a --- /dev/null +++ b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/Activator.java @@ -0,0 +1,61 @@ +package org.etsi.mts.tdl.openapi2tdl.next; + +import java.util.Hashtable; + +import org.etsi.mts.tdl.transform.AbstractTranslator; +import org.etsi.mts.tdl.transform.Converter; +import org.etsi.mts.tdl.transform.Generator; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +//public class Activator extends Plugin { +public class Activator implements BundleActivator { + + // The plug-in ID + public static final String PLUGIN_ID = "org.etsi.mts.tdl.openapi2tdl.next"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { +// super.start(context); + Hashtable properties = new Hashtable(); + properties.put("type", PLUGIN_ID); + context.registerService(Converter.class.getName(), new ConverterNext(), properties); + context.registerService(AbstractTranslator.class.getName(), new OpenAPI2TDLTranslatorNext(), properties); + context.registerService(Generator.class.getName(), new TestDocumentationGenerator(), properties); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; +// super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/ConverterNext.java b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/ConverterNext.java index af15ab57b7a6b46d8ced91f11978d06448050906..9e1340e3be5ff476c4b4f4a00499f821ba4f1266 100644 --- a/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/ConverterNext.java +++ b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/ConverterNext.java @@ -3,46 +3,50 @@ package org.etsi.mts.tdl.openapi2tdl.next; import java.io.File; import org.eclipse.emf.ecore.resource.Resource; -import org.etsi.mts.tdl.helper.TDLHelper; +import org.eclipse.emf.ecore.util.EcoreUtil; import org.etsi.mts.tdl.transform.AbstractTranslator; +import org.etsi.mts.tdl.transform.Converter; import org.openapitools.codegen.utils.ModelUtils; import io.swagger.parser.OpenAPIParser; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.parser.core.models.ParseOptions; import io.swagger.v3.parser.util.InlineModelResolver; -import org.etsi.mts.tdl.Package; +import org.etsi.mts.tdl.resources.ResourceHandler; -public class ConverterNext { +public class ConverterNext implements Converter { public static void main(String[] args) throws Exception { String filename = args[0]; - process(filename, filename+"-generated-new.tdltx"); + ConverterNext converter = new ConverterNext(); + converter.process(filename, filename+"-generated-new.tdltx"); } - public static String processToString(String inputPath, String outputPath) { + public String processToString(String inputPath, String outputPath) { return processToString(inputPath, outputPath, "SOURCE_MAPPING", "TARGET_MAPPING"); } - public static String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) { + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) { return processToString(inputPath, outputPath, sourceMapping, targetMapping, false); } - public static String getTargetPackageName(String inputPath) { + public String getTargetPackageName(String inputPath) { return AbstractTranslator.cleanName(new File(inputPath).getName()); } - public static String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping, boolean inline) { + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping, boolean inline) { // OpenAPI spec = parseSpec(inputPath); System.out.println("Exporting: "+outputPath+ " : "+ new File(outputPath).getAbsolutePath()); OpenAPI2TDLTranslatorNext translator = new OpenAPI2TDLTranslatorNext(); String content = "Package imported {}"; + //TODO: This is effectively broken.. try { - Resource tr = TDLHelper.create(outputPath); + Resource tr = ResourceHandler.create(outputPath); translator.setTargetResource(tr); translator.initTargetResource(getTargetPackageName(inputPath)); translator.translate(inputPath, sourceMapping, targetMapping, inline); - content = TDLHelper.getText(tr); + EcoreUtil.resolveAll(tr); + content = ResourceHandler.getText(tr); } catch (Exception e) { e.printStackTrace(); } @@ -50,17 +54,16 @@ public class ConverterNext { } - public static String process(String inputPath, String outputPath) { + public String process(String inputPath, String outputPath) { OpenAPI spec = parseSpec(inputPath); AbstractTranslator translator = new OpenAPI2TDLTranslatorNext(); String name = "imported"; try { - Resource tr = TDLHelper.create(outputPath); + Resource tr = ResourceHandler.create(outputPath); translator.setTargetResource(tr); translator.initTargetResource(translator.getCleanName(new File(inputPath).getName())); translator.translate(inputPath); - name = ((Package) tr.getContents().get(0)).getName(); - TDLHelper.store(tr, true); + ResourceHandler.store(tr, true); } catch (Exception e) { e.printStackTrace(); } @@ -90,4 +93,11 @@ public class ConverterNext { inlineModelResolver.flatten(openAPI); return openAPI; } + + @Override + public String getExtension() { + // TODO Auto-generated method stub + return "yaml"; + } + } diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/OpenAPI2TDLTranslatorNext.java b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/OpenAPI2TDLTranslatorNext.java index 86e308aac15974793263be1ae80569980697a088..5594f62116f300791216b785c782ca6fad3f305a 100644 --- a/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/OpenAPI2TDLTranslatorNext.java +++ b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/OpenAPI2TDLTranslatorNext.java @@ -1,6 +1,7 @@ package org.etsi.mts.tdl.openapi2tdl.next; import java.io.File; +import java.math.BigInteger; import java.util.Collections; import java.util.HashSet; import java.util.Hashtable; @@ -10,6 +11,7 @@ import java.util.Set; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.Platform; import org.eclipse.emf.ecore.resource.Resource; import org.etsi.mts.tdl.Annotation; import org.etsi.mts.tdl.AnnotationType; @@ -35,7 +37,7 @@ import org.etsi.mts.tdl.StructuredDataInstance; import org.etsi.mts.tdl.StructuredDataType; import org.etsi.mts.tdl.tdlFactory; import org.etsi.mts.tdl.tdlPackage; -import org.etsi.mts.tdl.helper.TDLHelper; +import org.etsi.mts.tdl.resources.ResourceHandler; import org.etsi.mts.tdl.transform.AbstractTranslator; import org.openapitools.codegen.ClientOptInput; import org.openapitools.codegen.CodegenConfig; @@ -54,10 +56,12 @@ import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.PathItem.HttpMethod; import io.swagger.v3.oas.models.Paths; +import io.swagger.v3.oas.models.media.Discriminator; import io.swagger.v3.oas.models.media.MediaType; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.parser.core.models.ParseOptions; import io.swagger.v3.parser.util.InlineModelResolver; @@ -71,6 +75,16 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { private Package theTdlPackage; + private StructuredDataType messageBody; + private StructuredDataType httpRequest; + private StructuredDataType httpResponse; + private CollectionDataType httpRequestParameters; + private EnumDataType httpParameterLocationEnum; + private EnumDataType httpMethodEnum; + + private DataResourceMapping httpAdapter; + private DataResourceMapping drmTarget; + public void translate(String filename) throws Exception { translate(filename, sourceMappingTag, targetMappingTag); } @@ -97,7 +111,7 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { drm.setResourceURI(new File(filename).getName()); - theTdlPackage = TDLHelper.getTdlPackage(getTargetResource()); + theTdlPackage = ResourceHandler.getTdlPackage(getTargetResource()); if (theTdlPackage != null) { ElementImport importTdl = tdlFactory.eINSTANCE.createElementImport(); importTdl.setImportedPackage(theTdlPackage); @@ -106,19 +120,25 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { getGeneratedPackage().getPackagedElement().remove(stringType); } - IProject project = TDLHelper.getProjectForResource(getTargetResource()); Preferences preferences = null; - if (project != null) { - ProjectScope ps = new ProjectScope(project); - preferences = ps.getNode(PropertyPage.PREFERENCE_SCOPE); + if (Platform.isRunning()) { + IProject project = ResourceHandler.getProjectForResource(getTargetResource()); + if (project != null) { + ProjectScope ps = new ProjectScope(project); + preferences = ps.getNode(PropertyPage.PREFERENCE_SCOPE); + } } - Package httpPackage = TDLHelper.getHttpPackage(getTargetResource()); + Package httpPackage = ResourceHandler.getHttpPackage(getTargetResource()); Package httpMessageBasedPackage = null; boolean useMessageBasedApi = true; - if (preferences != null) + boolean useSpecializedRequest = false; + String javaApiPackage = "generated.java"; + if (preferences != null) { useMessageBasedApi = !preferences.getBoolean(PropertyPage.PROCEDURE_BASED, false); - StructuredDataType messageBody = null; + useSpecializedRequest = preferences.getBoolean(PropertyPage.TYPED_REQUESTS, false); + javaApiPackage= preferences.get(PropertyPage.JAVA_API_PACKAGE, "generated.java"); + } if (useMessageBasedApi) { if (httpPackage != null) { packages: for (Package p : httpPackage.getNestedPackage()) { @@ -135,6 +155,23 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { ElementImport importHttp = tdlFactory.eINSTANCE.createElementImport(); importHttp.setImportedPackage(httpMessageBasedPackage); getGeneratedPackage().getImport().add(importHttp); + + for (PackageableElement e : httpMessageBasedPackage.getPackagedElement()) { + if (e.eClass().equals(tdlPackage.eINSTANCE.getStructuredDataType())) { + if (e.getName().equals("Request")) + httpRequest = (StructuredDataType) e; + if (e.getName().equals("Response")) + httpResponse = (StructuredDataType) e; + } else if (e.eClass().equals(tdlPackage.eINSTANCE.getEnumDataType())) { + if (e.getName().equals("Method")) + httpMethodEnum = (EnumDataType) e; + else if (e.getName().equals("Location")) + httpParameterLocationEnum = (EnumDataType) e; + } else if (e.eClass().equals(tdlPackage.eINSTANCE.getCollectionDataType())) { + if (e.getName().equals("Parameters")) + httpRequestParameters = (CollectionDataType) e; + } + } } } } @@ -158,15 +195,27 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { tdlImport.setImportedPackage(theTdlPackage); mappingsPackage.getImport().add(tdlImport); } - javaPackage = TDLHelper.getJavaPackage(getTargetResource()); + javaPackage = ResourceHandler.getJavaPackage(getTargetResource()); if (javaPackage != null) { ElementImport javaImport = tdlFactory.eINSTANCE.createElementImport(); javaImport.setImportedPackage(javaPackage); mappingsPackage.getImport().add(javaImport); } + Package httpJavaMappingsPackage = ResourceHandler.getHttpJavaMappingsPackage(getTargetResource()); + httpAdapter = null; + if (httpJavaMappingsPackage != null) { + ElementImport httpJavaImport = tdlFactory.eINSTANCE.createElementImport(); + httpJavaImport.setImportedPackage(httpJavaMappingsPackage); + mappingsPackage.getImport().add(httpJavaImport); + for (PackageableElement e : httpJavaMappingsPackage.getPackagedElement()) { + if (e instanceof DataResourceMapping && e.getName().equals("HttpAdapter")) + httpAdapter = (DataResourceMapping) e; + } + } + drmTarget = getTypeFor(targetMappingTag, tdlPackage.Literals.DATA_RESOURCE_MAPPING); mappingsPackage.getPackagedElement().add(drmTarget); - drmTarget.setResourceURI(preferences.get(PropertyPage.JAVA_API_PACKAGE, "generated.java")); + drmTarget.setResourceURI(javaApiPackage); if (javaPackage != null) { for (PackageableElement e : javaPackage.getPackagedElement()) { if (e.eClass().equals(tdlPackage.eINSTANCE.getAnnotationType()) @@ -233,36 +282,15 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { } - StructuredDataType httpRequest = null; - CollectionDataType httpRequestParameters = null; - EnumDataType httpParameterLocationEnum = null; - EnumDataType httpMethodEnum = null; - if (httpMessageBasedPackage != null) { - for (PackageableElement e : httpMessageBasedPackage.getPackagedElement()) { - if (e.eClass().equals(tdlPackage.eINSTANCE.getStructuredDataType())) { - if (e.getName().equals("Request")) - httpRequest = (StructuredDataType) e; - } else if (e.eClass().equals(tdlPackage.eINSTANCE.getEnumDataType())) { - if (e.getName().equals("Method")) - httpMethodEnum = (EnumDataType) e; - else if (e.getName().equals("Location")) - httpParameterLocationEnum = (EnumDataType) e; - } else if (e.eClass().equals(tdlPackage.eINSTANCE.getCollectionDataType())) { - if (e.getName().equals("Parameters")) - httpRequestParameters = (CollectionDataType) e; - } - } - } - if (useMessageBasedApi) { - createOperationWrapper(noContentOperations, httpRequest, httpMethodEnum, httpRequestParameters, httpParameterLocationEnum); + createOperationWrapper(noContentOperations, null, useSpecializedRequest); } for (PathOperation op : inlineSchemaOperations) { Schema schema = op.inlineSchema; schema.setName(op.path.substring(1) + "_body"); DataType dataType = translate(schema, "", messageBody); if (useMessageBasedApi) { - createOperationWrapper(Collections.singleton(op), httpRequest, httpMethodEnum, httpRequestParameters, httpParameterLocationEnum); + createOperationWrapper(Collections.singleton(op), dataType, useSpecializedRequest); } } for (String schemaName : model.getComponents().getSchemas().keySet()) { @@ -273,7 +301,7 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { if (useMessageBasedApi) { Set ops = schemaOperations.get(schemaName); if (ops != null) - createOperationWrapper(ops, httpRequest, httpMethodEnum, httpRequestParameters, httpParameterLocationEnum); + createOperationWrapper(ops, dataType, useSpecializedRequest); } } @@ -293,9 +321,7 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { return type; } - private void createOperationWrapper(Set ops, StructuredDataType httpRequest, - EnumDataType httpMethodEnum, CollectionDataType httpRequestParameters, - EnumDataType httpParameterLocationEnum) { + private void createOperationWrapper(Set ops, DataType bodyType, boolean useSpecializedRequest) { for (PathOperation pathOperation : ops) { Operation op = pathOperation.operation; @@ -305,7 +331,19 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { name = pathOperation.path; StructuredDataInstance requestData = getStructuredDataInstanceFor(name); - requestData.setDataType(httpRequest); + if (useSpecializedRequest && bodyType != null) { + StructuredDataType specializedRequest = getStructuredDataTypeFor(bodyType.getName() + "_Request"); + String bodyMemberName = "body_t"; + if (specializedRequest.getExtension().isEmpty()) { + addSuperType(specializedRequest, httpRequest); + Member bodyMember = getContentWithName(bodyMemberName, specializedRequest, tdlPackage.Literals.MEMBER); + bodyMember.setDataType(bodyType); + specializedRequest.getMember().add(bodyMember); + } + requestData.setDataType(specializedRequest); + } else { + requestData.setDataType(httpRequest); + } setMemberValue(requestData, "uri", pathOperation.path); @@ -358,8 +396,42 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { System.err.println("Unsupported parameter type: " + in + " at " + par.get$ref()); } } -// Member headersMember = findContentWithName("headers", httpRequest, tdlPackage.eINSTANCE.getMember()); -// Member parametersMember = findContentWithName("parameters", httpRequest, tdlPackage.eINSTANCE.getMember()); + + for (String responseCode : op.getResponses().keySet()) { + ApiResponse response = op.getResponses().get(responseCode); + StructuredDataInstance responseData = getStructuredDataInstanceFor(name + "_" + responseCode); + + DataType responseBodyType = null; + if (response.getContent() != null && response.getContent().get("application/json") != null) { + Schema responseSchema = response.getContent().get("application/json").getSchema(); + if (responseSchema != null) { + if (responseSchema.getName() == null) { + responseSchema.setName(name + "_" + responseCode + "_body"); + } + responseBodyType = translate(responseSchema, "", messageBody); + } + } + + if (useSpecializedRequest && responseBodyType != null) { + StructuredDataType specializedResponse = getStructuredDataTypeFor(responseBodyType.getName() + "_Response"); + String bodyMemberName = "body_t"; + if (specializedResponse.getExtension().isEmpty()) { + addSuperType(specializedResponse, httpResponse); + Member bodyMember = getContentWithName(bodyMemberName, specializedResponse, tdlPackage.Literals.MEMBER); + bodyMember.setDataType(responseBodyType); + specializedResponse.getMember().add(bodyMember); + } + responseData.setDataType(specializedResponse); + } else { + responseData.setDataType(httpResponse); + } + + if (responseCode.matches("\\d+")) { + setMemberValue(responseData, "status", Integer.valueOf(responseCode)); + } else if (responseCode.equals("default")) { + // TODO + } + } } } @@ -372,6 +444,11 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { LiteralValueUse dataUse = tdlFactory.eINSTANCE.createLiteralValueUse(); dataUse.setValue((String) value); assignment.setMemberSpec(dataUse); + } else if (value instanceof Integer) { + LiteralValueUse dataUse = tdlFactory.eINSTANCE.createLiteralValueUse(); + Long longValue = ((Integer)value).longValue(); + dataUse.setIntValue(BigInteger.valueOf(longValue)); + assignment.setMemberSpec(dataUse); } else if (value instanceof DataInstance) { DataElementUse dataUse = tdlFactory.eINSTANCE.createDataElementUse(); @@ -408,19 +485,19 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { @Override public void setTargetResource(Resource targetResource) { super.setTargetResource(targetResource); - Class resourceClass = targetResource.getClass(); do { // Flaky if (resourceClass.getSimpleName().equals("XtextResource")) { isXtext = true; break; - } + } resourceClass = resourceClass.getSuperclass(); } while (resourceClass != null); - if (isXtext) - xtextKyewords = TDLHelper.getTdlGrammarKeywords(); + if (isXtext) { + xtextKyewords = ResourceHandler.getTdlGrammarKeywords(); + } } private void addMapping(Schema schema, DataType dataType, String sourceMappingTag, String targetMappingTag) { @@ -446,8 +523,12 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { List xOf = schema.getAllOf(); if (xOf == null) xOf = schema.getAnyOf(); - if (xOf == null) - xOf = schema.getOneOf(); + // If there is a discriminator, then oneOf represents sub-types in an inheritance hierarchy. + // In this case, we don't want to "leak" all sub-type properties into the base type. + if (schema.getDiscriminator() == null) { + if (xOf == null) + xOf = schema.getOneOf(); + } if (xOf != null) { for (Schema ofSchema : xOf) this.getAllProperties(ofSchema, properties); @@ -456,7 +537,64 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { properties.putAll(schema.getProperties()); } + private void getAllRequired(Schema schema, Set required) { + String reference = schema.get$ref(); + if (reference != null) + schema = ModelUtils.getReferencedSchema(model, schema); + List xOf = schema.getAllOf(); + if (xOf == null) + xOf = schema.getAnyOf(); + // If there is a discriminator, then oneOf represents sub-types in an inheritance hierarchy. + // In this case, we don't want to "leak" all sub-type properties into the base type. + if (schema.getDiscriminator() == null) { + if (xOf == null) + xOf = schema.getOneOf(); + } + if (xOf != null) { + for (Schema ofSchema : xOf) + this.getAllRequired(ofSchema, required); + } + if (schema.getRequired() != null) + required.addAll(schema.getRequired()); + } + private DataType translate(Schema schema, String prefix, DataType superType) { + String reference = schema.get$ref(); + if (reference != null) { + Schema referencedSchema = ModelUtils.getReferencedSchema(model, schema); + referencedSchema.setName(ModelUtils.getSimpleRef(reference)); + return translate(referencedSchema, "", superType); + } + + Discriminator discriminator = schema.getDiscriminator(); + if (discriminator != null) { + DataType baseType = translateObject(schema, schema.getName()); + addSuperType(baseType, superType); + + List subTypes = schema.getOneOf(); + if (subTypes != null) { + for (Schema subSchemaRef : subTypes) { + translate(subSchemaRef, "", baseType); + } + } + return baseType; + } + + List allOf = schema.getAllOf(); + if (allOf != null) { + Schema refSchema = null; + int refCount = 0; + for (Schema s : allOf) { + if (s.get$ref() != null) { + refCount++; + refSchema = s; + } + } + if (refCount == 1) { + superType = translate(refSchema, "", null); + } + } + Map properties = new Hashtable<>(); this.getAllProperties(schema, properties); if (getSchemaType(schema) == null && properties.isEmpty()) { @@ -527,6 +665,8 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { private DataType translateObject(Schema schema, String name) { Map properties = new Hashtable<>(); this.getAllProperties(schema, properties); + Set required = new HashSet<>(); + this.getAllRequired(schema, required); StructuredDataType dataType = getStructuredDataTypeFor(name); if (properties.isEmpty() || !dataType.getMember().isEmpty()) { return dataType; @@ -544,6 +684,9 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { } Member m = getContentWithName((String) propertyName, dataType, tdlPackage.Literals.MEMBER); m.setDataType(memberType); + if (!required.contains(propertyName)) { + m.setIsOptional(true); + } if (m.container() == null) { dataType.getMember().add(m); } @@ -755,6 +898,48 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator { } } } + + if (httpAdapter != null) { + for (PackageableElement pe : getGeneratedPackage().getPackagedElement()) { + if (pe instanceof StructuredDataType) { + StructuredDataType type = (StructuredDataType) pe; + + boolean isRequest = false; + boolean isResponse = false; + for (org.etsi.mts.tdl.Extension ext : type.getExtension()) { + if (ext.getExtending() == httpRequest) isRequest = true; + if (ext.getExtending() == httpResponse) isResponse = true; + } + + if (isRequest || isResponse) { + String javaClass = isRequest ? "HttpRequestData" : "HttpResponseData"; + DataResourceMapping targetResource = resourceMapping; + + targetResource = httpAdapter; + + DataElementMapping eMapping = tdlFactory.eINSTANCE.createDataElementMapping(); + mappingsPackage.getPackagedElement().add(eMapping); + eMapping.setName(getCleanName(type.getName()) + "_Mapping"); + eMapping.setMappableDataElement(type); + eMapping.setElementURI(javaClass); + eMapping.setDataResourceMapping(targetResource); + Annotation ca = tdlFactory.eINSTANCE.createAnnotation(); + ca.setKey(classAnnotation); + eMapping.getAnnotation().add(ca); + + for (Member m : type.getMember()) { + if (m.getName().equals("body_t")) { + ParameterMapping pMapping = tdlFactory.eINSTANCE.createParameterMapping(); + eMapping.getParameterMapping().add(pMapping); + pMapping.setParameter(m); + pMapping.setParameterURI("body"); + } + } + } + } + } + } + //return super.postProcessSupportingFileData(objs); return objs; } diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/PropertyPage.java b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/PropertyPage.java index 69e0b132dc954adf77f6eb64cac7252a2900f72a..d23b6011de1b3e3838c6772ff5859236e1770d93 100644 --- a/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/PropertyPage.java +++ b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/PropertyPage.java @@ -23,7 +23,8 @@ public class PropertyPage extends FieldEditorPreferencePage implements IWorkbenc public static final String PROCEDURE_BASED = "ProcedureBased", GENERATE_JAVA_MAPPING = "GenerateJavaMapping", JAVA_GENERATOR = "JavaMappingGenerator", - JAVA_API_PACKAGE = "JavaApiPackage"; + JAVA_API_PACKAGE = "JavaApiPackage", + TYPED_REQUESTS = "TypedRequests"; public static final String PREFERENCE_SCOPE = "org.etsi.mts.tdl.openapi2tdl"; @@ -112,6 +113,10 @@ public class PropertyPage extends FieldEditorPreferencePage implements IWorkbenc BooleanFieldEditor procBased = new BooleanFieldEditor(PROCEDURE_BASED, "Procedure-based API", parent); addField(procBased); + parent = getFieldEditorParent(); + BooleanFieldEditor specializedRequest = new BooleanFieldEditor(TYPED_REQUESTS, "Generate typed requests/responses", parent); + addField(specializedRequest); + parent = getFieldEditorParent(); BooleanFieldEditor genJavaMappings = new BooleanFieldEditor(GENERATE_JAVA_MAPPING, "Generate type mappings for Java", parent); addField(genJavaMappings); diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/TestDocumentationGenerator.java b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/TestDocumentationGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..dc463fa90c1cb441f5bc15d044bc5e19f08d6acb --- /dev/null +++ b/plugins/org.etsi.mts.tdl.openapi2tdl.next/src/org/etsi/mts/tdl/openapi2tdl/next/TestDocumentationGenerator.java @@ -0,0 +1,39 @@ +package org.etsi.mts.tdl.openapi2tdl.next; + +import org.etsi.mts.tdl.openapi2tdl.next.doc.Doc; +import org.etsi.mts.tdl.transform.Converter; +import org.etsi.mts.tdl.transform.Generator; + +public class TestDocumentationGenerator implements Generator { + + @Override + public String getExtension() { + return "yaml"; + } + + @Override + public String processToString(String inputPath, String outputPath) { + // TODO Auto-generated method stub + Doc doc = new Doc(); + try { + doc.processModel(inputPath, true); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return doc.getContent().toString(); + } + + @Override + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) { + // TODO Auto-generated method stub + return processToString(inputPath, outputPath); + } + + @Override + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping, + boolean inline) { + return processToString(inputPath, outputPath); + } + +} diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/.classpath b/plugins/org.etsi.mts.tdl.openapi2tdl/.classpath deleted file mode 100644 index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/.project b/plugins/org.etsi.mts.tdl.openapi2tdl/.project deleted file mode 100644 index 5cbc827267c6c8d4ac136ea92adccd17c9266fc3..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/.project +++ /dev/null @@ -1,39 +0,0 @@ - - - org.etsi.mts.tdl.openapi2tdl - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - - - 1705077780112 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.openapi2tdl/META-INF/MANIFEST.MF deleted file mode 100644 index 7b71239eb5be39a8c8643b4ff4bb30a67f24489e..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/META-INF/MANIFEST.MF +++ /dev/null @@ -1,18 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: OpenAPI to TDL Generator -Bundle-SymbolicName: org.etsi.mts.tdl.openapi2tdl -Bundle-Version: 1.0.0.qualifier -Automatic-Module-Name: org.etsi.mts.tdl.openapi2tdl -Bundle-Vendor: ETSI -Require-Bundle: org.eclipse.core.runtime, - org.eclipse.core.resources, - com.reprezen.swagedit.openapi3, - com.reprezen.swagedit.core, - com.reprezen.swagedit.dependencies, - org.eclipse.emf.ecore, - org.etsi.mts.tdl.model, - org.etsi.mts.tdl.common, - com.google.guava;bundle-version="21.0.0" -Export-Package: org.etsi.mts.tdl.openapi2tdl -Bundle-RequiredExecutionEnvironment: JavaSE-11 diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/Converter.java b/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/Converter.java deleted file mode 100644 index 971fdf97f16e9e0b1b30825e70c6f9682e769b54..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/Converter.java +++ /dev/null @@ -1,478 +0,0 @@ -package org.etsi.mts.tdl.openapi2tdl; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import org.eclipse.emf.ecore.resource.Resource; -import org.etsi.mts.tdl.Annotation; -import org.etsi.mts.tdl.AnnotationType; -import org.etsi.mts.tdl.CollectionDataType; -import org.etsi.mts.tdl.Comment; -import org.etsi.mts.tdl.DataElementMapping; -import org.etsi.mts.tdl.DataResourceMapping; -import org.etsi.mts.tdl.DataType; -import org.etsi.mts.tdl.Element; -import org.etsi.mts.tdl.Member; -import org.etsi.mts.tdl.Package; -import org.etsi.mts.tdl.ParameterMapping; -import org.etsi.mts.tdl.SimpleDataType; -import org.etsi.mts.tdl.StructuredDataType; -import org.etsi.mts.tdl.tdlFactory; - -import com.reprezen.jsonoverlay.JsonOverlay; -import com.reprezen.jsonoverlay.MapOverlay; -import com.reprezen.jsonoverlay.PropertiesOverlay; -import com.reprezen.jsonoverlay.Reference; -import com.reprezen.kaizen.oasparser.OpenApi3Parser; -import com.reprezen.kaizen.oasparser.model3.OpenApi3; -import com.reprezen.kaizen.oasparser.model3.Schema; -import com.reprezen.kaizen.oasparser.ovl3.SchemaImpl; - - -public class Converter { - private static Collection tdlTokens; - - private final OpenApi3 model; - private Package pkg = null; - private final AnnotationType warningAnnotationType = createWarningAnnotationType(); - private final static String dataRescourceMappingName = "OpenAPIMapping"; - private String filename; - - public OpenApi3 getModel() { - return model; - } - public Package getPackage() { - return pkg; - } - - /** - * Number used to name anonymous CollectionDataTypes (-> Collection0, Collection1, ...) - */ - private int anonymousCollectionCounter = 0; - /** - * Number used to name anonymous StructuresDataTypes (-> Object0, Object1, ...) - */ - private int anonymousObjectCounter = 0; - - /** - * List of warning messages generated while converting - */ - private List warningList = new ArrayList<>(); - - private final Map simpleDataTypeByName = new HashMap<>(); - private final Map collectionDataTypeBySchema = new HashMap<>(); - private final Map structuredDataTypeBySchema = new HashMap<>(); - - public List getWarnings() { - return warningList; - } - - public Converter(OpenApi3 model) { - this.model = model; - } - - public Converter(String filename) throws FileNotFoundException { - this.model = loadOpenApi3(filename); - this.filename = filename; - } - //TODO: Time for a complete rewrite! - private void setName(Element elem, String name) { - if (tdlTokens.contains("'" + name + "'")) { - warningList.add(new KeywordEscapedWarning(String.format("Name '%s' is a TDL keyword", name))); - name = "^" + name; - } - name = name.replaceAll("-", "_") - .replaceAll("^_", "N_") - .replaceAll(" ", "_") - .replaceAll("\\.", "_"); - elem.setName(name); -} - - public AnnotationType createWarningAnnotationType() { - AnnotationType wAT = tdlFactory.eINSTANCE.createAnnotationType(); - setName(wAT, "Warning"); - return wAT; - } - - /** - * Convert an OpenApi3 model to a TDL Package - */ - public Package exportToTdlPackage() { - Package p = tdlFactory.eINSTANCE.createPackage(); - setName(p, model.getInfo().getTitle()); - - p.getPackagedElement().add(warningAnnotationType); - - // generate schemas - for (Schema schema: model.getSchemas().values()) { - if (schema.getType()==null) { - //TODO: add warning or handle gracefully - continue; - } - DataType type = createDataTypeFromSchema(schema); - if (!addDescription(type, schema)) { - warningList.add(new DescriptionMissingWarning(String.format("Missing description for schema %s", schema.getName()))); - } - } - - // add data types to package - p.getPackagedElement().addAll(simpleDataTypeByName.values()); - p.getPackagedElement().addAll(collectionDataTypeBySchema.values()); - p.getPackagedElement().addAll(structuredDataTypeBySchema.values()); - - // Create OpenAPI data mapping - DataResourceMapping mapping = tdlFactory.eINSTANCE.createDataResourceMapping(); - setName(mapping, dataRescourceMappingName); - mapping.setResourceURI(setQuotationMarks(filename)); - p.getPackagedElement().add(mapping); - - // Only consider top-level structured data types - for (Schema schema: model.getSchemas().values()) { - if (schema.getType()==null) { - schema.setType("TODO_UNSPECIFIED_SCHEMA_TYPE"); - } - if (//schema.getType()==null || - schema.getType().equals("object")) { - SchemaWrapper wrappedSchema = new SchemaWrapper(schema); - StructuredDataType structuredDT = structuredDataTypeBySchema.get(wrappedSchema); - // Create Mapping Elements - DataElementMapping mappingElement = tdlFactory.eINSTANCE.createDataElementMapping(); - setName(mappingElement, "OpenAPI" + structuredDT.getName()); - mappingElement.setDataResourceMapping(mapping); - mappingElement.setElementURI(setQuotationMarks("#/components/schemas/" + structuredDT.getName())); - mappingElement.setMappableDataElement(structuredDT); - - for (Member member : structuredDT.getMember()) { - // Create Parameter mapping for each member of structured data type - ParameterMapping parameterMapping = tdlFactory.eINSTANCE.createParameterMapping(); - parameterMapping.setParameter(member); - parameterMapping.setParameterURI(setQuotationMarks(member.getName())); - - mappingElement.getParameterMapping().add(parameterMapping); - } - p.getPackagedElement().add(mappingElement); - } - } - return p; - } - - public DataType createDataTypeFromSchema(Schema schema) { - if (schema.getType() == null) { - //TODO: why? - schema.setType("TODO_UNSPECIFIED_SCHEMA_TYPE"); - //TODO: also add proper hierarchical naming - } - if (//schema.getType() == null || - schema.getType().equals("object")) { - return createStructuredDataTypeFromSchema(schema); - } else if (schema.getType().equals("array")) { - return createCollectionDataTypeFromSchema(schema); - } else { - return createSimpleDataTypeFromSchema(schema); - } - } - - private void checkSchemaForExample(Schema schema) { - if ((schema.getExample() == null)) { - warningList.add(new ExampleMissingWarning("Missing example for schema " + schema.getName())); - } - } - - /** - * Adds the schema description to the given type. Returns true on success and false if the schema has no description - */ - private boolean addDescription(Element type, Schema schema) { - if (schema.getDescription() == null || schema.getDescription().equals("")) { - return false; - } - Comment comment = tdlFactory.eINSTANCE.createComment(); - comment.setBody(setQuotationMarks(schema.getDescription())); - type.getComment().add(comment); - return true; - } - - public CollectionDataType createCollectionDataTypeFromSchema(Schema schema) { - SchemaWrapper wrapped = new SchemaWrapper(schema); - if (collectionDataTypeBySchema.containsKey(wrapped)) { - return collectionDataTypeBySchema.get(wrapped); - } - - boolean isAnonymous = !model.getSchemas().values().stream().anyMatch(e -> e == schema); - - CollectionDataType newCollection = tdlFactory.eINSTANCE.createCollectionDataType(); - setName(newCollection, isAnonymous ? "Collection" + anonymousCollectionCounter++ : schema.getName()); - - //check naming conventions - if(isAnonymous) { - setName(newCollection, "Collection" + anonymousCollectionCounter++); - String name = ""; - Object parentSchema = schema; - while (parentSchema instanceof Schema) { - //TODO: reflection hack - JsonOverlay jo = (JsonOverlay) parentSchema; - try { - Field parent = JsonOverlay.class.getDeclaredField("parent"); - parent.setAccessible(true); - parentSchema = parent.get(jo); - //Skip to previous parent, - //TODO: double check this is reliable - //TODO: also check if it is applicable for structured data in general - if (parentSchema instanceof MapOverlay) { - parent = JsonOverlay.class.getDeclaredField("parent"); - parent.setAccessible(true); - parentSchema = parent.get((JsonOverlay)parentSchema); - } - - Field pathInParent = JsonOverlay.class.getDeclaredField("pathInParent"); - pathInParent.setAccessible(true); - String parentPath = (String) pathInParent.get(jo); - - name = parentPath+"___"+name; - } catch (Exception e) { - // TODO Auto-generated catch block - System.err.println("ERROR: "+e.getMessage()); - } - } - setName(newCollection, name.replaceAll("___$", "")); - - } - else { - String typeName = schema.getName(); - if(typeName != null) { - if(Character.isLowerCase(typeName.charAt(0))) { - Annotation an = tdlFactory.eINSTANCE.createAnnotation(); - an.setKey(warningAnnotationType); - an.setValue(setQuotationMarks("Naming conventions not followed: First letter should be upper case.")); - newCollection.getAnnotation().add(an); - warningList.add(new NamingConventionWarning(String.format("The Collection %s is not following naming conventions. First letter should be upper case.", schema.getName()))); - } - } - setName(newCollection, schema.getName()); - } - - DataType itemType = createDataTypeFromSchema(schema.getItemsSchema()); - newCollection.setItemType(itemType); - if (isAnonymous) { - itemType.setName(newCollection.getName()+itemType.getName().replaceFirst("^.+?___", "___")); - } - - Optional optionalReplacement = collectionDataTypeBySchema.values().stream().filter(coll -> coll.getItemType() == itemType && coll.getName().matches("Collection\\d+")).findFirst(); - if (isAnonymous && optionalReplacement.isPresent()) { - return optionalReplacement.get(); - } - - collectionDataTypeBySchema.put(wrapped, newCollection); - - return newCollection; - } - - public StructuredDataType createStructuredDataTypeFromSchema(Schema schema) { - SchemaWrapper wrapped = new SchemaWrapper(schema); - if (schema.getName() != null && structuredDataTypeBySchema.containsKey(wrapped)) { - return structuredDataTypeBySchema.get(wrapped); - } - - checkSchemaForExample(schema); - - StructuredDataType newStructure = tdlFactory.eINSTANCE.createStructuredDataType(); - - String prefixedName = ""; - Object parentSchema = schema; - while (parentSchema instanceof Schema) { - //TODO: reflection hack - JsonOverlay jo = (JsonOverlay) parentSchema; - try { - Field parent = JsonOverlay.class.getDeclaredField("parent"); - parent.setAccessible(true); - parentSchema = parent.get(jo); - - Field pathInParent = JsonOverlay.class.getDeclaredField("pathInParent"); - pathInParent.setAccessible(true); - String parentPath = (String) pathInParent.get(jo); - - prefixedName = parentPath+"___"+prefixedName; - if (parentSchema instanceof MapOverlay) { - //skip one level - Field nextParent = JsonOverlay.class.getDeclaredField("parent"); - nextParent.setAccessible(true); - parentSchema = nextParent.get((JsonOverlay) parentSchema); - } - } catch (Exception e) { - // TODO Auto-generated catch block - System.err.println("ERROR: "+e.getMessage()); - } - } - if(schema.getName()==null) { - setName(newStructure, "Object" + anonymousObjectCounter++); - setName(newStructure, prefixedName.replaceAll("___$", "")); - } - else { - String typeName = schema.getName(); - if(typeName != null) { - if(Character.isLowerCase(typeName.charAt(0))) { - Annotation an = tdlFactory.eINSTANCE.createAnnotation(); - an.setKey(warningAnnotationType); - an.setValue(setQuotationMarks("Naming conventions not followed: First letter should be upper case.")); - newStructure.getAnnotation().add(an); - warningList.add(new NamingConventionWarning(String.format("The StructuredDataType %s is not following naming conventions. First letter should be upper case.", schema.getName()))); - } - } - setName(newStructure, schema.getName()); - setName(newStructure, prefixedName.replaceAll("___$", "")); - } - - structuredDataTypeBySchema.put(wrapped, newStructure); - - boolean containsCorrectIdProperty = false; - String idPropName = newStructure.getName().substring(0, 1).toLowerCase() + newStructure.getName().substring(1) + "Id"; - for (String propertyName : schema.getProperties().keySet()) { - Schema memberSchema = schema.getProperty(propertyName); - DataType memberType = createDataTypeFromSchema(memberSchema); - if (!(memberType instanceof SimpleDataType)) { - System.out.println("structure type:" +prefixedName); - memberType.setName(newStructure.getName()+"___"+memberType.getName().replaceAll(".+?___", "")); - System.out.println("member type:" +memberType.getName()); - } - - Member member = tdlFactory.eINSTANCE.createMember(); - - setName(member, propertyName); - if (propertyName.equals(idPropName)) { - containsCorrectIdProperty = true; - } - if(Character.isUpperCase(propertyName.charAt(0))){ - Annotation an = tdlFactory.eINSTANCE.createAnnotation(); - an.setKey(warningAnnotationType); - an.setValue(setQuotationMarks("Naming conventions not followed: First letter of a property should be lower case.")); - member.getAnnotation().add(an); - NamingConventionWarning warning = new NamingConventionWarning(String.format("The StructuredDataType %s is not following naming conventions. Properties should start with a lower case letter.", newStructure.getName())); - if(!warningList.contains(warning)){ - warningList.add(warning); - } - } - - member.setDataType(memberType); - if (!addDescription(member, memberSchema)) { - warningList.add(new DescriptionMissingWarning(String.format("Missing description for property %s of schema %s", memberSchema.getName(), schema.getName()))); - } - newStructure.getMember().add(member); - } - if(!containsCorrectIdProperty) { - Annotation an = tdlFactory.eINSTANCE.createAnnotation(); - an.setKey(warningAnnotationType); - an.setValue(setQuotationMarks("The DataType does not contain an Id-property that follows the naming conventions (DataTypeName+\"Id\").")); - newStructure.getAnnotation().add(an); - warningList.add(new NamingConventionWarning(String.format("The StructuredDataType %s does not contain an Id-property that follows the naming conventions (DataTypeName+\"Id\").", schema.getName()))); - } - - return newStructure; - } - - public SimpleDataType createSimpleDataTypeFromSchema(Schema schema) { - String name = schema.getType(); - - if (simpleDataTypeByName.containsKey(name)) { - return simpleDataTypeByName.get(name); - } - - SimpleDataType type = tdlFactory.eINSTANCE.createSimpleDataType(); - setName(type, schema.getType()); - simpleDataTypeByName.put(name, type); - - return type; - } - - /** - * Save a TDL package to a file - */ -// public static void saveTdlan2(Package p, String filename) throws IOException { -// Resource resource = TDLHelper.create(filename); -// -// resource.getContents().add(p); -// try { -// TDLHelper.store(resource); -// } catch (Exception e) { -// throw new IOException(String.format("Error while writing tdlan2 file: %s: '%s'", e.getClass().getName(), e.getMessage()), e); -// } -// } - - /** - * Load OpenApi3 model from file - */ - public static OpenApi3 loadOpenApi3(String filename) throws FileNotFoundException { - File file = new File(filename); - if (!file.exists()) { - throw new FileNotFoundException(String.format("File '%s' does not exist", filename)); - } - OpenApi3 model; - try { - model = new OpenApi3Parser().parse(file, true); - } catch (Exception e) { - throw new RuntimeException(String.format("Error while parsing the yaml file: %s: '%s'", e.getClass().getName(), e.getMessage()), e); - } - return model; - } - - public void runConversion() { - pkg = exportToTdlPackage(); - } -// public void saveResult(String filename) throws IllegalStateException, IOException { -// if (pkg == null) { -// throw new IllegalStateException("Cannot save result before conversion is executed"); -// } -// saveTdlan2(pkg, filename); -// } - - private String setQuotationMarks(String s) { - return //TODO: this is only needed for legacy configuration.. - "\"" + - s - .replaceAll("\"", "\\\\\"") - + "\"" - ; - } - public static Collection getTdlTokens() { - return tdlTokens; - } - public static void setTdlTokens(Collection tdlTokens) { - Converter.tdlTokens = tdlTokens; - } -} - - -/** - * Wrapper for Schema objects to include the name in the equals method. - * equals(other) now returns true for SchemaWrapper objects wrapping the same Schema object. - */ -class SchemaWrapper { - private final Schema schema; - public SchemaWrapper(Schema schema) { - this.schema = schema; - } - - @Override - public boolean equals(Object o) { - if (o instanceof SchemaWrapper) { - SchemaWrapper other = (SchemaWrapper) o; - return schema == other.schema; - } - return false; - } - - @Override - public int hashCode() { - return schema.hashCode(); - } - - public String getName() { - return schema.getName(); - } -} diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/DescriptionMissingWarning.java b/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/DescriptionMissingWarning.java deleted file mode 100644 index ccb4a6e6079ad5b0d239fd739493f8433d77250a..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/DescriptionMissingWarning.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.etsi.mts.tdl.openapi2tdl; - -public class DescriptionMissingWarning extends Warning{ - - public DescriptionMissingWarning(String msg) { - super(msg); - } -} diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/ExampleMissingWarning.java b/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/ExampleMissingWarning.java deleted file mode 100644 index dc055689396293fef234b5186a56416ac19b078a..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/ExampleMissingWarning.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.etsi.mts.tdl.openapi2tdl; - -public class ExampleMissingWarning extends Warning{ - - public ExampleMissingWarning(String msg) { - super(msg); - } -} diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/KeywordEscapedWarning.java b/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/KeywordEscapedWarning.java deleted file mode 100644 index 1646205ac2ff3af77ef6cfa2dfe770ec961da942..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/KeywordEscapedWarning.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.etsi.mts.tdl.openapi2tdl; - -public class KeywordEscapedWarning extends Warning { - - public KeywordEscapedWarning(String msg) { - super(msg); - } - -} diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/NamingConventionWarning.java b/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/NamingConventionWarning.java deleted file mode 100644 index ca6cf2b69b0e29d8ff97a002cbe0dc98f288d1c6..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/NamingConventionWarning.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.etsi.mts.tdl.openapi2tdl; - -public class NamingConventionWarning extends Warning{ - - public NamingConventionWarning(String msg) { - super(msg); - } - - @Override - public boolean equals(Object o) { - if(!(o instanceof NamingConventionWarning)) - return false; - if(!((NamingConventionWarning) o).getMessage().equals(this.getMessage())) - return false; - - return true; - } -} diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/OpenAPI2TDLTranslator.java b/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/OpenAPI2TDLTranslator.java deleted file mode 100644 index af4f152248135b5c436f2462f68263444a0efdc8..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/OpenAPI2TDLTranslator.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.etsi.mts.tdl.openapi2tdl; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.Arrays; -import java.util.Optional; - -import org.etsi.mts.tdl.CollectionDataType; -import org.etsi.mts.tdl.DataElementMapping; -import org.etsi.mts.tdl.DataResourceMapping; -import org.etsi.mts.tdl.DataType; -import org.etsi.mts.tdl.Member; -import org.etsi.mts.tdl.PackageableElement; -import org.etsi.mts.tdl.StructuredDataType; -import org.etsi.mts.tdl.tdlFactory; -import org.etsi.mts.tdl.tdlPackage; -import org.etsi.mts.tdl.transform.AbstractTranslator; - -import com.reprezen.jsonoverlay.JsonOverlay; -import com.reprezen.jsonoverlay.Reference; -import com.reprezen.kaizen.oasparser.OpenApi3Parser; -import com.reprezen.kaizen.oasparser.model3.OpenApi3; -import com.reprezen.kaizen.oasparser.model3.Schema; -import com.reprezen.kaizen.oasparser.ovl3.SchemaImpl; - -public class OpenAPI2TDLTranslator extends AbstractTranslator { - - - public void translate(String filename) throws Exception { -// Converter.setTdlTokens(Arrays.asList(new String[] {"'name'", "'type'", "'size'", "'instance'"})); -// Converter converter = new Converter(filename); -// converter.runConversion(); -// getGeneratedPackage().getNestedPackage().add(converter.getPackage()); - //TODO: refine according to other translators - //TODO: separate validation into another component - - OpenApi3 model = loadOpenApi3(filename); - drm = getTypeFor("SOURCE_MAPPING", tdlPackage.Literals.DATA_RESOURCE_MAPPING); - drm.setResourceURI("\""+new File(filename).getName()+"\""); - drmTarget = getTypeFor("TARGET_MAPPING", tdlPackage.Literals.DATA_RESOURCE_MAPPING); - //TODO: make configurable - drmTarget.setResourceURI("\"generated/java\""); - for (Schema schema: model.getSchemas().values()) { - DataType dataType = translate(schema, ""); - addMapping(schema, dataType); - } - - } - - private void addMapping(Schema schema, DataType dataType) { - DataElementMapping sourceMapping = getTypeFor(schema.getName()+"_SOURCE_MAPPING", tdlPackage.Literals.DATA_ELEMENT_MAPPING); - sourceMapping.setMappableDataElement(dataType); - sourceMapping.setElementURI("\"#/components/schemas/"+schema.getName()+"\""); - sourceMapping.setDataResourceMapping(drm); - - //TODO: make configurable - DataElementMapping targetMapping = getTypeFor(schema.getName()+"_TARGET_MAPPING", tdlPackage.Literals.DATA_ELEMENT_MAPPING); - targetMapping.setMappableDataElement(dataType); - //TODO: transform / adapt mapping based on configuration? - targetMapping.setElementURI("\""+schema.getName()+"\""); - targetMapping.setDataResourceMapping(drmTarget); - - } - - private DataType translate(Schema schema, String prefix) { - if (schema.getType()==null && schema.getProperties().isEmpty()) { - if (schema.getName() == null) { - System.out.println("Why?"); - } - return getSimpleDataTypeFor(schema.getName()); - } else { - String name = prefix+schema.getName(); - if (schema.getName() == null) { - name = prefix+"___item"; - } - if (!schema.getProperties().isEmpty() || - schema.getType().equals("object")) { - return translateObject(schema, name); - } else if (schema.getType().equals("array")) { - return translateArray(schema, name); - } else { - return getSimpleDataTypeFor(schema.getType()); - } - } - } - - private DataType translateObject(Schema schema, String name) { - StructuredDataType dataType = getStructuredDataTypeFor(name); - for (String propertyName : schema.getProperties().keySet()) { - Schema propertySchema = schema.getProperty(propertyName); - Reference reference = ((SchemaImpl) propertySchema)._getCreatingRef(); - DataType memberType = null; - if (reference!=null) { - memberType = translate(propertySchema, ""); - } else { - memberType = translate(propertySchema, name+"___"); - } - Member m = getContentWithName(propertyName, dataType, tdlPackage.Literals.MEMBER); - m.setDataType(memberType); - if (m.container()==null) { - dataType.getMember().add(m); - } - } - return dataType; - } - - private DataType translateArray(Schema schema, String name) { - SchemaImpl itemsSchema = (SchemaImpl) schema.getItemsSchema(); - CollectionDataType collectionType = getTypeFor(name, tdlPackage.Literals.COLLECTION_DATA_TYPE); - Reference reference = itemsSchema._getCreatingRef(); - if (reference!=null) { - DataType itemType = translate(itemsSchema, ""); - collectionType.setItemType(itemType); - } else { - DataType itemType = translate(itemsSchema, name+""); - collectionType.setItemType(itemType); - } - return collectionType; - } - - - public static OpenApi3 loadOpenApi3(String filename) throws FileNotFoundException { - File file = new File(filename); - if (!file.exists()) { - throw new FileNotFoundException(String.format("File '%s' does not exist", filename)); - } - OpenApi3 model; - try { - model = new OpenApi3Parser().parse(file, true); - } catch (Exception e) { - throw new RuntimeException(String.format("Error while parsing the yaml file: %s: '%s'", e.getClass().getName(), e.getMessage()), e); - } - return model; - } - -} diff --git a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/Warning.java b/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/Warning.java deleted file mode 100644 index cb5c8665e252c524959060a095b4233a05ef0817..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.openapi2tdl/src/org/etsi/mts/tdl/openapi2tdl/Warning.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.etsi.mts.tdl.openapi2tdl; - -public abstract class Warning { - private final String message; - - public Warning(String msg) { - message = msg; - } - - @Override - public String toString() { - return message; - } - - public String getMessage() { - return message; - } -} diff --git a/plugins/org.etsi.mts.tdl.perspective/.classpath b/plugins/org.etsi.mts.tdl.perspective/.classpath index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.perspective/.classpath +++ b/plugins/org.etsi.mts.tdl.perspective/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.perspective/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.perspective/.settings/org.eclipse.jdt.core.prefs index c9545f06a4120d5b4a1228fb19f67a1171bc0f5b..23fa13b170502d5a7f7a0549188dbc454a7cf0c8 100644 --- a/plugins/org.etsi.mts.tdl.perspective/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.perspective/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.perspective/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.perspective/META-INF/MANIFEST.MF index 749bf9dfb5da85c11f1417f3109da7f2ef9bdadc..984ca060398c93bfc3b57be24802a04748770ad8 100644 --- a/plugins/org.etsi.mts.tdl.perspective/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.perspective/META-INF/MANIFEST.MF @@ -7,6 +7,6 @@ Bundle-Activator: org.etsi.mts.tdl.perspective.Activator Bundle-Vendor: European Telecommunications Standards Institute (ETSI) Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Automatic-Module-Name: org.etsi.mts.tdl.perspective Bundle-ActivationPolicy: lazy diff --git a/plugins/org.etsi.mts.tdl.project/.classpath b/plugins/org.etsi.mts.tdl.project/.classpath index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.project/.classpath +++ b/plugins/org.etsi.mts.tdl.project/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.project/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.project/.settings/org.eclipse.jdt.core.prefs index c9545f06a4120d5b4a1228fb19f67a1171bc0f5b..23fa13b170502d5a7f7a0549188dbc454a7cf0c8 100644 --- a/plugins/org.etsi.mts.tdl.project/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.project/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.project/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.project/META-INF/MANIFEST.MF index 0409c141030bf580b14b06d426b43e7c28547436..7342676439e77c6011c6be3fd6e515ccd75e425e 100644 --- a/plugins/org.etsi.mts.tdl.project/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.project/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-SymbolicName: org.etsi.mts.tdl.project;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Vendor: ETSI Automatic-Module-Name: org.etsi.mts.tdl.project -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Require-Bundle: org.eclipse.core.runtime;bundle-version="3.26.100", org.eclipse.core.resources, org.eclipse.ui diff --git a/plugins/org.etsi.mts.tdl.rt.ui/.classpath b/plugins/org.etsi.mts.tdl.rt.ui/.classpath index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.rt.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.rt.ui/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.rt.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.rt.ui/.settings/org.eclipse.jdt.core.prefs index 7adc0fb9a0d32bd6b4e3ce6f305ab7165208865c..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.rt.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.rt.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.rt.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.rt.ui/META-INF/MANIFEST.MF index a1603acd1198124eab07e2881ea3aad8d0373acc..b7554e728ef7d66481050891cef3d24d3a274efe 100644 --- a/plugins/org.etsi.mts.tdl.rt.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.rt.ui/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Ui +Automatic-Module-Name: org.etsi.mts.tdl.rt.ui +Bundle-Name: TDL Resource Tools UI Bundle-SymbolicName: org.etsi.mts.tdl.rt.ui;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.etsi.mts.tdl.tools.rt.ui.Activator @@ -10,11 +11,10 @@ Require-Bundle: org.eclipse.ui, org.eclipse.ui.editors;bundle-version="3.5.0", org.eclipse.ui.ide;bundle-version="3.5.0", org.eclipse.ui.workbench, - com.google.inject, org.eclipse.xtext.ui, org.eclipse.emf.ecore, org.eclipse.xtext, org.etsi.mts.tdl.model Bundle-ActivationPolicy: lazy Import-Package: org.eclipse.emf.common.util -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 diff --git a/plugins/org.etsi.mts.tdl.rt.ui/icons/T3Icon.png b/plugins/org.etsi.mts.tdl.rt.ui/icons/T3Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8e2c90479919a7d1c1c28b2e401bf6d0ae9554b8 Binary files /dev/null and b/plugins/org.etsi.mts.tdl.rt.ui/icons/T3Icon.png differ diff --git a/plugins/org.etsi.mts.tdl.rt.ui/icons/ValidateIcon.png b/plugins/org.etsi.mts.tdl.rt.ui/icons/ValidateIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..177f063c819ce8113f405a56aa94954e77093aad Binary files /dev/null and b/plugins/org.etsi.mts.tdl.rt.ui/icons/ValidateIcon.png differ diff --git a/plugins/org.etsi.mts.tdl.rt.ui/plugin.xml b/plugins/org.etsi.mts.tdl.rt.ui/plugin.xml index 068fde6d6aa52bac3de462f832b85718da797771..1592275cb52f977517a26d7f0c9fa3b4e0566021 100644 --- a/plugins/org.etsi.mts.tdl.rt.ui/plugin.xml +++ b/plugins/org.etsi.mts.tdl.rt.ui/plugin.xml @@ -1,7 +1,6 @@ - - + + + + + + + + @@ -20,15 +34,14 @@ commandId="org.etsi.mts.tdl.tools.rt.ui.commands.translateCommand" class="org.etsi.mts.tdl.tools.rt.ui.handlers.TranslationHandler"> - - - - + + + + @@ -45,6 +58,29 @@ id="org.etsi.mts.tdl.tools.rt.ui.menus.translateCommand"> + + + + + + + + @@ -56,8 +92,23 @@ tooltip="Translate TDL Model" id="org.etsi.mts.tdl.tools.rt.ui.toolbars.translateCommand"> + + + + - - + + + + diff --git a/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/TP2TDDialog.java b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/TP2TDDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..f9e820dae64bfc338890ae66de53320b137924c6 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/TP2TDDialog.java @@ -0,0 +1,209 @@ +package org.etsi.mts.tdl.tools.rt.ui; + +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.prefs.Preferences; + +public class TP2TDDialog extends TitleAreaDialog { + + private Text prefixField; + private Text suffixField; + private Text substituteField; + private Text withField; + private Button removeAnnotationsButton; + private Button removeAnnotatedBlocksButton; + private Button markAsDerivedButton; + + //TODO: numbers, first / last? + private String regex = "[a-zA-Z_]"; + + + //DONE: store between runs + private String prefix = ""; + private String suffix = "_TDs"; + private String substitute = "TP_"; + private String with = "TD_"; + private boolean removeAnnotations = false; + private boolean removeAnnotatedBlocks = false; + private boolean markAsDerived = false; + private IEclipsePreferences preferences; + private Preferences tp2td; + + public TP2TDDialog(Shell parentShell) { + super(parentShell); + preferences = ConfigurationScope.INSTANCE + .getNode("org.etsi.mts.tdl.converters"); + tp2td = preferences.node("tp2td"); + } + + @Override + public void create() { + super.create(); + setTitle("Transform TPs to TDs"); + setMessage("Customise the tranformation process", IMessageProvider.INFORMATION); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite area = (Composite) super.createDialogArea(parent); + Composite container = new Composite(area, SWT.NONE); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(2, false); + container.setLayout(layout); + + prefix = tp2td.get("prefix", ""); + suffix = tp2td.get("suffix", "_TDs"); + substitute = tp2td.get("substitute", "TP_"); + with = tp2td.get("with", "TD_"); + removeAnnotations = tp2td.getBoolean("removeAnnotations", false); + removeAnnotatedBlocks = tp2td.getBoolean("removeAnnotatedBlocks", false); + markAsDerived = tp2td.getBoolean("markAsDerived", true); + + + //DONE: validate to make sure that at least one is used + // - validate special characters (only characters, numbers, underscores) + // -> basic validation done, no numbers at present (need to check first character in case) + //TODO: fix layouts + prefixField = createTextField(container, "Package prefix", prefix); + addValidation(prefixField, regex); + suffixField = createTextField(container, "Package suffix", suffix); + addValidation(suffixField, regex); + + substituteField = createTextField(container, "Substitute in name", substitute); + addValidation(substituteField, substitute); + withField = createTextField(container, "With", with); + addValidation(withField, regex); + + //TODO: hints + removeAnnotationsButton = createOption(container, "Remove annotations", isRemoveAnnotations()); + removeAnnotatedBlocksButton = createOption(container, "Remove annotated blocks", isRemoveAnnotatedBlocks()); + markAsDerivedButton = createOption(container, "Mark target file as derived", isMarkAsDerived()); + removeAnnotationsButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e-> { + if (!removeAnnotationsButton.getSelection() && removeAnnotatedBlocksButton.getSelection()) { + removeAnnotatedBlocksButton.setSelection(false); + } + })); + removeAnnotatedBlocksButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e-> { + if (!removeAnnotationsButton.getSelection() && removeAnnotatedBlocksButton.getSelection()) { + removeAnnotationsButton.setSelection(true); + } + })); + + return area; + } + + //TODO: there ought to be JFace shortcut for this... or use bindings? + private Text createTextField(Composite container, String label, String value) { + Label l = new Label(container, SWT.NONE); + l.setText(label); + + GridData d = new GridData(); + d.grabExcessHorizontalSpace = true; + d.horizontalAlignment = GridData.FILL; + var text = new Text(container, SWT.BORDER); + text.setLayoutData(d); + text.setText(value); + return text; + } + private void addValidation(Text text, String regex) { + text.addVerifyListener(e->validateRegEx(e, regex)); + } + private Object validateRegEx(VerifyEvent e, String regex) { + e.doit = e.text.matches(regex) || e.keyCode == SWT.DEL || e.keyCode == SWT.BS; + return null; + } + + private Button createOption(Composite container, String label, boolean value) { + final Button button = new Button (container, SWT.CHECK); + GridData d = new GridData(); + d.grabExcessHorizontalSpace = true; + d.horizontalAlignment = GridData.FILL; + button.setLayoutData(d); + button.setText(label); + button.setSelection(value); + return button; + } + + + @Override + protected boolean isResizable() { + return true; + } + + // save content of the Text fields because they get disposed + // as soon as the Dialog closes + + private void saveInput() { + prefix = prefixField.getText(); + suffix = suffixField.getText(); + substitute = substituteField.getText(); + with = withField.getText(); + removeAnnotations = removeAnnotationsButton.getSelection(); + removeAnnotatedBlocks = removeAnnotatedBlocksButton.getSelection(); + markAsDerived = markAsDerivedButton.getSelection(); + + tp2td.put("prefix", prefix); + tp2td.get("suffix", suffix); + tp2td.put("substitute", substitute); + tp2td.get("with", with); + tp2td.putBoolean("removeAnnotations", removeAnnotations); + tp2td.putBoolean("removeAnnotatedBlocks", removeAnnotatedBlocks); + tp2td.putBoolean("markAsDerived", markAsDerived); + + try { + // forces the application to save the preferences + preferences.flush(); + } catch (Exception e2) { + e2.printStackTrace(); + } + + } + + @Override + protected void okPressed() { + saveInput(); + super.okPressed(); + } + + public String getPrefix() { + return prefix; + } + + public String getSuffix() { + return suffix; + } + + public boolean isRemoveAnnotations() { + return removeAnnotations; + } + + public boolean isRemoveAnnotatedBlocks() { + return removeAnnotatedBlocks; + } + + public String getSubstitute() { + return substitute; + } + + public String getWith() { + return with; + } + + public boolean isMarkAsDerived() { + return markAsDerived; + } +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/ToggleHandler.java b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/ToggleHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..9af299ef310999375fa552cdd9a1637b6c5f5032 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/ToggleHandler.java @@ -0,0 +1,61 @@ +package org.etsi.mts.tdl.tools.rt.ui; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.State; +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.ui.IStartup; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.etsi.mts.tdl.Validator; +import org.etsi.mts.tdl.tdlPackage; +import org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +public class ToggleHandler implements IStartup { + public static final String TOGGLE_VALIDATOR_COMMAND_ID = "org.etsi.mts.tdl.tools.rt.ui.commands.toggleValidatorCommand"; + + @Override + public void earlyStartup() { + boolean state = getToggleState(TOGGLE_VALIDATOR_COMMAND_ID); + if (state) { + enablePlugin(); + } else { + disablePlugin(); + } + } + + public static boolean getToggleState(String commandId) { + ICommandService commandService = PlatformUI.getWorkbench().getService(ICommandService.class); + if (commandService != null) { + Command command = commandService.getCommand(commandId); + State state = command.getState("org.eclipse.ui.commands.toggleState"); + if (state != null) { + return (Boolean) state.getValue(); + } + } + return true; // default value + } + + public static void toggleState(boolean currentState) { + if (!currentState) { + enablePlugin(); + } else { + disablePlugin(); + } + } + + static void enablePlugin() { + Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.model"); + BundleContext context = bundle.getBundleContext(); + Validator.registerValidator("model/tdl-constraints.ocl", tdlPackage.eINSTANCE, context); + Validator.registerValidator("model/tdl-structured-constraints.ocl", StructuredObjectivesPackage.eINSTANCE, context); + } + + static void disablePlugin() { +// EValidator.Registry.INSTANCE.remove(tdlPackage.eINSTANCE); + Validator.removeValidator(tdlPackage.eINSTANCE); + Validator.removeValidator(StructuredObjectivesPackage.eINSTANCE); + } + +} diff --git a/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/ReloadValidationHandler.java b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/ReloadValidationHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..f5d4e3444224341a3ba4496eb89a46f10c37a4eb --- /dev/null +++ b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/ReloadValidationHandler.java @@ -0,0 +1,58 @@ +package org.etsi.mts.tdl.tools.rt.ui.handlers; + +import java.util.LinkedHashMap; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.ecore.EValidator; +import org.eclipse.ui.IWorkbenchWindow; +import org.etsi.mts.tdl.Validator; +import org.etsi.mts.tdl.tdlPackage; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Our sample handler extends AbstractHandler, an IHandler base class. + * @see org.eclipse.core.commands.IHandler + * @see org.eclipse.core.commands.AbstractHandler + */ +public class ReloadValidationHandler extends AbstractHandler { + LinkedHashMap targetFormats = new LinkedHashMap<>(); + + private IWorkbenchWindow window; + + /** + * The constructor. + */ + public ReloadValidationHandler() { + init(); + } + + private void init() { + } + + + /** + * the command has been executed, so extract extract the needed information + * from the application context. + */ + public Object execute(ExecutionEvent event) throws ExecutionException { + EValidator.Registry.INSTANCE.remove(tdlPackage.eINSTANCE); + Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.model"); + BundleContext context = bundle.getBundleContext(); + Validator.registerValidator("model/tdl-constraints.ocl", tdlPackage.eINSTANCE, context); + return null; + } + + public void init(IWorkbenchWindow window) { + this.window = window; + } + + @Override + public boolean isEnabled() { + return true; + } + +} diff --git a/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/TP2TDHandler.java b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/TP2TDHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..4f92fd74fab1b5f07acead9772f513b2b9ce927b --- /dev/null +++ b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/TP2TDHandler.java @@ -0,0 +1,170 @@ +package org.etsi.mts.tdl.tools.rt.ui.handlers; + +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.resource.XtextResourceSet; +import org.etsi.mts.tdl.Annotation; +import org.etsi.mts.tdl.Block; +import org.etsi.mts.tdl.CompoundBehaviour; +import org.etsi.mts.tdl.Element; +import org.etsi.mts.tdl.Package; +import org.etsi.mts.tdl.TestDescription; +import org.etsi.mts.tdl.tools.rt.ui.TP2TDDialog; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +public class TP2TDHandler extends AbstractHandler{ + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + ISelection selection = HandlerUtil.getCurrentSelection(event); + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + IFile file = null; + if (input != null && input instanceof FileEditorInput) { + file = ((FileEditorInput) input).getFile(); + } else if (selection !=null && selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + Object firstElement = structuredSelection.getFirstElement(); + if (firstElement instanceof IFile) { + file = (IFile) firstElement; + } + } + + if (file !=null) { + //TODO: copied from translation handler, there has to be a better way.. or at least reused.. + URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); + Injector injector = Guice.createInjector(); + XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class); +// ResourceSet rs = new ResourceSetImpl(); + XtextResourceSet rs = resourceSet; + Resource r = rs.getResource(uri, true); + EcoreUtil.resolveAll(r); + + + var dialog = new TP2TDDialog(Display.getDefault().getActiveShell()); + // just to demonstrate how to set the title background color + dialog.setTitleAreaColor(Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY).getRGB()); + + // now open the dialog + dialog.create(); + if (dialog.open() == Window.OK) { + //Handle... + //TODO: encapsulate + URI targetURI = URI.createURI(uri.toString()); + String ext = targetURI.fileExtension(); + String last = targetURI.trimFileExtension().lastSegment(); + last = dialog.getPrefix() + last + dialog.getSuffix(); + targetURI = targetURI.trimSegments(1).appendSegment(last).appendFileExtension(ext); +// XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class); +// resourceSet = rs; + Resource tr = resourceSet.createResource(targetURI); + tr.getContents().addAll(EcoreUtil.copyAll(r.getContents())); + + processModel(tr, dialog.getPrefix(), dialog.getSuffix(), + dialog.getSubstitute(), dialog.getWith(), + dialog.isRemoveAnnotations(), dialog.isRemoveAnnotatedBlocks() + ); + + //TODO: this also has to be reused + try { + EcoreUtil.resolveAll(tr); +// EcoreUtil2.resolveAll(r, null); +// HashMap options = Maps.newHashMap(); +// options.put(XtextResource.OPTION_RESOLVE_ALL, true); + tr.save(null); + } catch (Exception e1) { + System.err.println(" Translation: "+e1.getMessage()); + e1.printStackTrace(); + //TODO: provide an error dialog, fall back to XF, indicate approximate location based on error message / details + } + //DONE: Make optional + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IPath targetPath = file.getFullPath().removeLastSegments(1).append(last).addFileExtension(ext); + IFile targetFile = workspace.getRoot().getFile(targetPath); + try { + if (dialog.isMarkAsDerived()) { + targetFile.setDerived(true); + } else { + targetFile.setDerived(false); + } + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + return null; + } + + private void processModel(Resource resource, String prefix, String suffix, String substitute, String with, boolean removeAnnotations, boolean removeAnnotatedBlocks) { + //update names for all packages + var packages = EcoreUtil2.eAllOfType(resource.getContents().get(0), Package.class); + for (var p : packages) { + p.setName(prefix+p.getName()+suffix); + } + //remove annotations + if (removeAnnotations) { + var tds = EcoreUtil2.eAllOfType(resource.getContents().get(0), TestDescription.class); + for (var td : tds) { + td.setName(td.getName().replace(substitute, with)); + if (!removeAnnotatedBlocks) { + //naive approach, clean up blocks as well + removeElements(td, Annotation.class); + } else { + //more sophisticated approach, clean up blocks as well + var annotations = EcoreUtil2.eAllOfType(td, Annotation.class); + for (var a : annotations) { + if (a.getAnnotatedElement() instanceof CompoundBehaviour) { + var cb = (CompoundBehaviour) a.getAnnotatedElement(); + if (cb.container() instanceof Block) { + var container = (Block) cb.container(); + var behaviours = cb.getBlock().getBehaviour(); + //TODO: order? + container.getBehaviour().addAll(behaviours); + EcoreUtil2.delete(cb, true); + } + } else { + EcoreUtil2.delete(a, true); + } + } + } + + } + } + + } + + private void removeElements(Resource tr, Class type) { + removeElements(tr.getContents().get(0), type); + } + + private void removeElements(EObject element, Class type) { + List elements = EcoreUtil2.eAllOfType(element, type); + EcoreUtil2.deleteAll(elements, true); + } + +} diff --git a/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/ToggleValidation.java b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/ToggleValidation.java new file mode 100644 index 0000000000000000000000000000000000000000..e1aa69ffcbaa1815734e69bd8d11d8d825bc9e5f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.rt.ui/src/org/etsi/mts/tdl/tools/rt/ui/handlers/ToggleValidation.java @@ -0,0 +1,40 @@ +package org.etsi.mts.tdl.tools.rt.ui.handlers; +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.menus.UIElement; +import org.etsi.mts.tdl.tools.rt.ui.ToggleHandler; + +public class ToggleValidation extends AbstractHandler implements IElementUpdater { + + + public ToggleValidation() { + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + boolean currentState = HandlerUtil.toggleCommandState(event.getCommand()); + ToggleHandler.toggleState(currentState); + ICommandService commandService = (ICommandService) + HandlerUtil.getActiveWorkbenchWindow(event) + .getService(ICommandService.class); + commandService.refreshElements(ToggleHandler.TOGGLE_VALIDATOR_COMMAND_ID, null); + return null; + } + + @Override + public void updateElement(UIElement element, Map parameters) { + if (ToggleHandler.getToggleState(ToggleHandler.TOGGLE_VALIDATOR_COMMAND_ID)) { + element.setText("Deactivate TDL Validation"); + } else { + element.setText("Activate TDL Validation"); + } + + } + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.standalone/.classpath b/plugins/org.etsi.mts.tdl.standalone/.classpath index e6a6586ec78cec9e5e3e32707331fa3ca8623ac6..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.standalone/.classpath +++ b/plugins/org.etsi.mts.tdl.standalone/.classpath @@ -1,13 +1,7 @@ - - - - - + - - diff --git a/plugins/org.etsi.mts.tdl.standalone/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.standalone/.settings/org.eclipse.jdt.core.prefs index a58ebdcad300d0a088dcbd63941d2c89e78a4f98..1e0cb16bbc76c98cc42fff6b95cc023b7eb74830 100644 --- a/plugins/org.etsi.mts.tdl.standalone/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.standalone/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -12,4 +12,4 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.standalone/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.standalone/META-INF/MANIFEST.MF index a2aeb527510d7dd1d3545b7fb8848a3a21f72521..1aabed90b136a7eb16dcf4020d38019e6dd35f34 100644 --- a/plugins/org.etsi.mts.tdl.standalone/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.standalone/META-INF/MANIFEST.MF @@ -10,18 +10,17 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.emf.ecore, org.eclipse.xtext, - org.eclipse.ocl.xtext.essentialocl, + org.eclipse.ocl.xtext.completeocl, org.etsi.mts.tdl.model, org.etsi.mts.tdl.common, org.etsi.mts.tdl.helper, org.etsi.mts.tdl.to2tdl, org.etsi.mts.tdl.asn2tdl, org.etsi.mts.tdl.openapi2tdl.next, - org.etsi.mts.tdl.constraints, - org.eclipse.epsilon.evl.engine, org.etsi.mts.tdl.tools.to.docx.poi, org.etsi.mts.tdl.json2tdl, org.eclipse.emf.common, org.etsi.mts.tdl.ttcn3, - de.ugoe.cs.swe.TTCN3 + de.ugoe.cs.swe.TTCN3, + org.etsi.mts.tdl.yang2tdl Bundle-ClassPath: . diff --git a/plugins/org.etsi.mts.tdl.standalone/lib/ASN1.tdltx b/plugins/org.etsi.mts.tdl.standalone/lib/ASN1.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..e5303d33e7c2d11179894cc1a6d8acda8cd74825 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.standalone/lib/ASN1.tdltx @@ -0,0 +1,95 @@ +Note: "Based on TR 103 119 v1.4.1" +@Version: "1.0.0" +Package ASN1 { + Import all from TDL + + //Constraints + //Specific typed constraints for each type + //Constraint AsnBitString + //Constraint AsnOctetString + //Constraint AsnUtcString + //or + //Generic constraint with corresponding detail in + //the constraint quantifier/qualifier: + //e.g. "[01]+'B" or more generically "AsnBitString"? + Constraint ASN1String + Constraint ASN1DateTime + Constraint ASN1Real + Constraint ASN1ObjectIdentifier + + //Types + //BITSTRING + Type BITSTRING {ASN1String:"[01]+'B"} + //or + //Type BITSTRING {ASN1String:"AsnBitString"} + //or + //Type BITSTRING {AsnBitString} + + //OCTETSTRING + Type OCTETSTRING {ASN1String:"[A-F0-9]+'H"} + //or + //Type OCTETSTRING {AsnOctetString} + //or + //Type OCTETSTRING {ASN1String:"AsnOctetString"} + + //BMPString + Type BMPString {ASN1String} + //IA5String + Type IA5String {ASN1String} + //GeneralString + Type GeneralString {ASN1String} + //GraphicString + Type GraphicString {ASN1String} + //NumericString + Type NumericString {ASN1String: "[0-9\\s]+"} + //PrintableString + Type PrintableString {ASN1String} + //TeletexString + Type TeletexString {ASN1String} + //T61String + Type T61String {ASN1String} + //UniversalString + Type UniversalString {ASN1String} + //UTF8String + Type UTF8String {ASN1String} + //VideotexString + Type VideotexString {ASN1String} + //VisibleString + Type VisibleString {ASN1String} + + //UTCTime + Type UTCTime {ASN1DateTime:"YYMMDDhhmm[ss]Z"} + //Type UTCTime {ASN1String:"YYMMDDhhmm[ss]Z"} + //or + //Type UTCTime {ASN1String:"AsnOctetString"} + //or + //Type UTCTime {ASN1DateTime:"AsnOctetString"} + //or + //Type UTCTime {AsnUtcString} + + //GeneralizedTime + Type GeneralizedTime {ASN1DateTime:"YYYYMMDDHH[MM[SS[.fff]]]Z"} + //DATE + Type DATE {ASN1DateTime:"YYYY-MM-DD"} + //TIME-OF-DAY + Type TimeOfDay {ASN1DateTime:"hh:mm:ss"} + //DATE-TIME + Type DateTime {ASN1DateTime:"YYYY-MM-DDThh:mm:ss"} + //INTEGER + //already defined in TDL -> use that + //Type Integer + //REAL + //originally mapped to string with constraint, would override standard + Type Real {ASN1Real} + //BOOLEAN + //already defined in TDL -> use that + //Type Integer + //NULL + Type Null + //OBJECTIDENTIFIER + Type ObjectIdentifier {ASN1ObjectIdentifier} + + //RELATIVE OBJECT OBJECTIDENTIFIER + //use ObjectIdentifier above + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.standalone/lib/HTTP.tdltx b/plugins/org.etsi.mts.tdl.standalone/lib/HTTP.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..7e2c4b71535f0f479bef1421c435f403a0be98b3 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.standalone/lib/HTTP.tdltx @@ -0,0 +1,172 @@ +@Version: "1.0.0" +Package HTTP { + + Package MessageBasedConfiguration { + Import all from MessageBased + Message Gate HTTPGate accepts Request,Response + Message Gate HTTPSGate accepts Request,Response + Component API { + // Add variables and timers here or define new component types and configurations + gate HTTPGate http + gate HTTPSGate https + } + Configuration BasicClientServer { + API client as Tester, + API poller as Tester, + API server as SUT, + connect client::http to server::http + } + } + + Note : "Message based types and instances" + Package MessageBased { + Import all from TDL + + // HTTP methods + Enumerated Method { + Method GET, + Method POST, + Method PUT, + Method PATCH, + Method DELETE + } + + // Generic Request type + Structure Request ( + String uri, + optional Method method, + optional Headers headers, + optional Parameters parameters, + optional QueryParameters queryParameters, + optional PathParameters pathParameters, + optional Body body + ) + + // Generic Response type + Structure Response ( + optional Integer status, + optional String statusMessage, + optional Headers headers, + optional Body body + ) + + // Supporting types + Collection Parameters of Parameter + Structure Parameter ( + Location location, + String ^name, + String ^value + ) + Enumerated Location { + Location path, + Location query, + // TODO may need a structure, not necessarily relevant in standardized testing + Location cookie + } + + Structure PathParameters () + Structure QueryParameters () + + Collection Headers of Header + Structure Header ( + String ^name, + String ^value + ) + + // Base body for extension + Structure Body () + + // Basic string body + Structure StringBody extends Body ( + String text + ) + + // Basic wrapper for collection responses + Structure CollectionBody extends Body ( + Bodies items + ) + + // Any body can be included + // If consistent type is needed, a custom subtype shall be defined and used + Collection Bodies of Body + // Custom collection data instances can be defined + // - inline in the responses + // - predefined as a separate data element + + // Custom collection data instances can be defined + // to enforce type consistency specific for API + + // Basic form body + Structure FormBody extends Body ( + String field, + String content + ) + } + + Package Templates { + Import all from MessageBased + + // Generic Request instances + Request rGET ( + method = GET + ) + Request rPOST ( + method = POST + ) + Request rPUT ( + method = PUT + ) + Request rPATCH ( + method = PATCH + ) + Request rDELETE ( + method = DELETE + ) + + // Generic Response instances, name = status code + Response r200 ( + statusMessage = "OK" + ) + Response r201 ( + statusMessage = "Created" + ) + Response r204 ( + statusMessage = "No Content" + ) + Response r400 ( + statusMessage = "Bad Request" + ) + Response r401 ( + statusMessage = "Unauthorized" + ) + Response r403 ( + statusMessage = "Forbidden" + ) + Response r404 ( + statusMessage = "Not Found" + ) + + // Generic Response instances, name = status message + Response OK ( + status = 200 + ) + Response Created ( + status = 201 + ) + Response NoContent ( + status = 204 + ) + Response BadRequest ( + status = 400 + ) + Response NotFound ( + status = 404 + ) + Response NotAuthorized ( + status = 401 + ) + Response Forbidden ( + status = 403 + ) + } +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.standalone/lib/HttpJavaMappings.tdltx b/plugins/org.etsi.mts.tdl.standalone/lib/HttpJavaMappings.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..7e460a4ee4de11c3e8e7a375adc84930d3caffa0 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.standalone/lib/HttpJavaMappings.tdltx @@ -0,0 +1,58 @@ +Package HttpJavaMappings { + Import all from Tdl + Import all from Java + Import all from HTTP.MessageBased + + @JavaPackage + @MappingName : "Java" + Use "org.etsi.mts.tdl.execution.java.adapters.http" as HttpAdapter + + @JavaClass + Map Request to "HttpRequestData" in HttpAdapter as Request_Mapping { + uri -> "uri", + method -> "method", + headers -> "headers", + parameters -> "parameters", + body -> "body" + } + @JavaClass + Map Response to "HttpResponseData" in HttpAdapter as Response_Mapping { + status -> "status", + statusMessage -> "statusMessage", + headers -> "headers", + body -> "body" + } + @JavaClass + Map Header to "HttpHeader" in HttpAdapter as Header_Mapping { + ^name -> "name", + ^value -> "value" + } + @JavaClass + Map Parameter to "HttpRequestParameter" in HttpAdapter as Parameter_Mapping { + location -> "location", + ^name -> "name", + ^value -> "value" + } + @JavaClass + Map Location to "HttpParameterLocation" in HttpAdapter as Location_Mapping + + @JavaClass + @MappingName : "Java" + Use "org.etsi.mts.tdl.execution.java.adapters.http.HttpParameterLocation" as HttpParameterLocation + Map path to "path" in HttpParameterLocation as path_mapping + Map query to "query" in HttpParameterLocation as query_mapping + Map cookie to "cookie" in HttpParameterLocation as cookie_mapping + + + @JavaClass + Map Method to "HttpMethod" in HttpAdapter as Method_Mapping + + @JavaClass + @MappingName : "Java" + Use "org.etsi.mts.tdl.execution.java.adapters.http.HttpMethod" as HttpMethod + Map GET to "GET" in HttpMethod as GET_mapping + Map POST to "POST" in HttpMethod as POST_mapping + Map PUT to "PUT" in HttpMethod as PUT_mapping + Map PATCH to "PATCH" in HttpMethod as PATCH_mapping + Map DELETE to "DELETE" in HttpMethod as DELETE_mapping +} diff --git a/plugins/org.etsi.mts.tdl.standalone/lib/Java.tdltx b/plugins/org.etsi.mts.tdl.standalone/lib/Java.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..8ff1e8bcda025612233a2d3e056ccc28e7d9dafa --- /dev/null +++ b/plugins/org.etsi.mts.tdl.standalone/lib/Java.tdltx @@ -0,0 +1,56 @@ +Package Java { + Import all from Tdl + + /* Applied to a DataResourceMapping to specify a package */ + Annotation JavaPackage + /* Applied to a DataElementMapping to specify an instance method */ + Annotation JavaMethod + /* Applied to a DataElementMapping to specify an class method */ + Annotation JavaStaticMethod + /* Applied to a DataResourceMapping or DataElementMapping to specify a class */ + Annotation JavaClass + /* Applied to a DataElementMapping to specify a field (of a class) */ + Annotation JavaField + /* Applied to a DataElementMapping to specify a static field (of a class) */ + Annotation JavaStaticField + /* Applied to a ParameterMapping to specify an instance method that returns the value of a field */ + Annotation JavaGetter + /* Applied to a ParameterMapping to specify an instance method that sets the field value */ + Annotation JavaSetter + + + @JavaPackage + @MappingName : "Java" + Use "java.lang" as JavaLang + Map Boolean to "Boolean" in JavaLang as Boolean_mapping + Map Integer to "Integer" in JavaLang as Integer_mapping + Map String to "String" in JavaLang as String_mapping + + + + @JavaPackage + @MappingName : "Java" + Use "org.etsi.mts.tdl.execution.java.tri" as Tri + + @JavaClass + Map Verdict to "Verdict" in Tri as Verdict_Mapping + + @JavaClass + @MappingName : "Java" + Use "org.etsi.mts.tdl.execution.java.tri.Verdict" as VerdictClass + Map pass to "pass" in VerdictClass as pass_mapping + Map fail to "fail" in VerdictClass as fail_mapping + Map inconclusive to "inconclusive" in VerdictClass as inconclusive_mapping + + + @JavaPackage + @MappingName : "Java" + Use "org.etsi.mts.tdl.execution.java.rt.core" as RuntimeCore + + @JavaClass + @MappingName : "Java" + Use "org.etsi.mts.tdl.execution.java.rt.core.TimeUnit" as TimeUnitClass + Map second to "Second" in TimeUnitClass as second_mapping + + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.standalone/lib/Standard.tdltx b/plugins/org.etsi.mts.tdl.standalone/lib/Standard.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..681efa80a4dfdd8620cb1aa00936ec40042f9ddd --- /dev/null +++ b/plugins/org.etsi.mts.tdl.standalone/lib/Standard.tdltx @@ -0,0 +1,57 @@ +Package TDL { + //TODO: extract to standard library + Constraint length + Constraint minLength + Constraint maxLength + Constraint range + Constraint format + Constraint union + Constraint uniontype + + Type Boolean + Type Integer + Type String + Type Verdict + + //TODO: these do not work at present -> literal values take precedence? + Boolean ^true + Boolean ^false + Boolean True + Boolean False + + Verdict pass + Verdict fail + Verdict inconclusive + + Time second + + Annotation Master + Annotation MappingName + + //standard annotations for STO + Annotation Initial conditions + Annotation Expected behaviour + Annotation Final conditions + Annotation Test Purpose Description + Annotation when + Annotation then + Annotation PICS + + Predefined == returns Boolean + Predefined != returns Boolean + Predefined and returns Boolean + Predefined or returns Boolean + Predefined xor returns Boolean + Predefined not returns Boolean + Predefined < returns Boolean + Predefined > returns Boolean + Predefined <= returns Boolean + Predefined >= returns Boolean + Predefined + + Predefined - + Predefined * + Predefined / + Predefined mod + Predefined size returns Integer + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/Tdl.tdltx b/plugins/org.etsi.mts.tdl.standalone/lib/Tdl.tdltx similarity index 100% rename from plugins/org.etsi.mts.tdl.library/src/org/etsi/mts/tdl/library/Tdl.tdltx rename to plugins/org.etsi.mts.tdl.standalone/lib/Tdl.tdltx diff --git a/plugins/org.etsi.mts.tdl.standalone/lib/TdlRuntime.tdltx b/plugins/org.etsi.mts.tdl.standalone/lib/TdlRuntime.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..07cd10d7322ab592da097e98561c6fa6375010fd --- /dev/null +++ b/plugins/org.etsi.mts.tdl.standalone/lib/TdlRuntime.tdltx @@ -0,0 +1,3 @@ +Package TdlRuntime { + Annotation Language +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.standalone/lib/YANG.tdltx b/plugins/org.etsi.mts.tdl.standalone/lib/YANG.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..67aa4a7f38564358585510aef293672022abc217 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.standalone/lib/YANG.tdltx @@ -0,0 +1,3 @@ +Package YANG { + Constraint choice +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.standalone/src/org/etsi/mts/tdl/standalone/Standalone.java b/plugins/org.etsi.mts.tdl.standalone/src/org/etsi/mts/tdl/standalone/Standalone.java index d956cb35cf37bfd729c1c099548a871c959b8c5e..2240e6cc4f7495b6e3c6475a6fdb853541c7c347 100644 --- a/plugins/org.etsi.mts.tdl.standalone/src/org/etsi/mts/tdl/standalone/Standalone.java +++ b/plugins/org.etsi.mts.tdl.standalone/src/org/etsi/mts/tdl/standalone/Standalone.java @@ -1,17 +1,12 @@ package org.etsi.mts.tdl.standalone; -import de.ugoe.cs.swe.TTCN3StandaloneSetup; import java.io.File; import java.io.FilenameFilter; -import java.net.URL; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.CodeSource; -import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; import java.util.List; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -21,42 +16,43 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.epsilon.evl.execute.UnsatisfiedConstraint; import org.eclipse.ocl.pivot.ExpressionInOCL; import org.eclipse.ocl.pivot.utilities.OCL; import org.eclipse.ocl.pivot.utilities.ParserException; import org.eclipse.ocl.pivot.utilities.Query; import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.etsi.mts.tdl.Behaviour; import org.etsi.mts.tdl.ComponentInstance; import org.etsi.mts.tdl.ComponentInstanceRole; +import org.etsi.mts.tdl.CompoundBehaviour; import org.etsi.mts.tdl.Extension; import org.etsi.mts.tdl.GateType; -import org.etsi.mts.tdl.Package; -import org.etsi.mts.tdl.Behaviour; -import org.etsi.mts.tdl.CompoundBehaviour; -import org.etsi.mts.tdl.BoundedLoopBehaviour; -import org.etsi.mts.tdl.AlternativeBehaviour; -import org.etsi.mts.tdl.ConditionalBehaviour; -import org.etsi.mts.tdl.ProcedureCall; -import org.etsi.mts.tdl.Interaction; import org.etsi.mts.tdl.Message; +import org.etsi.mts.tdl.Package; +import org.etsi.mts.tdl.SimpleDataType; import org.etsi.mts.tdl.StructuredDataType; import org.etsi.mts.tdl.TestConfiguration; import org.etsi.mts.tdl.TestDescription; +import org.etsi.mts.tdl.tdlFactory; import org.etsi.mts.tdl.tdlPackage; import org.etsi.mts.tdl.asn2tdl.ASN2TDLTranslator; -import org.etsi.mts.tdl.constraints.evl.Validator; import org.etsi.mts.tdl.helper.TDLHelper; -import org.etsi.mts.tdl.impl.CompoundBehaviourImpl; import org.etsi.mts.tdl.json2tdl.JSON2TDLTranslator; import org.etsi.mts.tdl.json2tdl.TDL2JSONTranslator; import org.etsi.mts.tdl.openapi2tdl.next.OpenAPI2TDLTranslatorNext; import org.etsi.mts.tdl.openapi2tdl.next.doc.Doc; +import org.etsi.mts.tdl.resources.ResourceHandler; import org.etsi.mts.tdl.tools.to.docx.poi.Generator; import org.etsi.mts.tdl.transform.AbstractTranslator; -import org.etsi.mts.tdl.ttcn3.Transform; +import org.etsi.mts.tdl.ttcn3.TTCN3Renderer; +import org.etsi.mts.tdl.util.tdlResourceFactoryImpl; +import org.etsi.mts.tdl.yang2tdl.Yang2TDLTranslator; + +import de.ugoe.cs.swe.TTCN3StandaloneSetup; public class Standalone { static String sourceExtension = "tdltx"; @@ -64,20 +60,23 @@ public class Standalone { static String openapiExtension = "yaml"; static String asnExtension = "asn"; static String jsonExtension = "json"; + static String yangExtension = "yang"; private List modes = new ArrayList<>(); private String path = ""; private boolean recursive = true; enum MODE { + test, all, list, debug, evaluateOCL, validateOCL, validate, translate, exportDoc, exportJSON, - importOpenAPI, importASN1, importJSON, + importOpenAPI, importASN1, importJSON, importYANG, openAPIDoc,exportTTCN3,generateDiagrams } public static void main(String[] args) throws Exception { + TDLHelper.init(); Standalone app = new Standalone(); //TODO: expose as arguments @@ -124,6 +123,43 @@ public class Standalone { // app.path = "examples/validation/Naming.tdltx.tdl"; // app.modes.add(MODE.validateOCL); + + if (app.selected(MODE.test)) { + String extension = ".tdlan2"; +// extension = ".tdltx"; + ResourceSet resSet = new ResourceSetImpl(); + resSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(extension, new tdlResourceFactoryImpl()); + resSet.getPackageRegistry().put(tdlPackage.eNS_URI, tdlPackage.eINSTANCE); + Resource res = resSet.createResource(URI.createURI("path"+extension)); + Package p = tdlFactory.eINSTANCE.createPackage(); + p.setName("TestSuite"); + var s = tdlFactory.eINSTANCE.createSimpleDataType(); + s.setName("String"); + p.getPackagedElement().add(s); + var m = tdlFactory.eINSTANCE.createStructuredDataType(); + m.setName("Type_A"); + var mm = tdlFactory.eINSTANCE.createMember(); + mm.setName("_name"); + mm.setDataType(s); + m.getMember().add(mm); + p.getPackagedElement().add(m); + var i = tdlFactory.eINSTANCE.createStructuredDataInstance(); + i.setName("Instance_A"); + i.setDataType(m); + var ma = tdlFactory.eINSTANCE.createMemberAssignment(); + ma.setMember(mm); + var lv = tdlFactory.eINSTANCE.createLiteralValueUse(); + lv.setValue("a2"); + ma.setMemberSpec(lv); + i.getMemberAssignment().add(ma); + p.getPackagedElement().add(i); + res.getContents().add(p); + try { + res.save(null); + } catch (IOException e) { + e.printStackTrace(); + } + } if (app.selected(MODE.list)) { String path = pathOrDefault(app.path, "examples/basics"); @@ -194,6 +230,11 @@ public class Standalone { app.processElements(path, asnExtension, app::importASN1); } + if (app.selected(MODE.importYANG)) { + String path = pathOrDefault(app.path, "examples/asn1"); + app.processElements(path, yangExtension, app::importYANG); + } + if (app.selected(MODE.generateDiagrams)) { String path = pathOrDefault(app.path, "examples/validation/Example.tdltx"); app.processElements(path, asnExtension, app::generateDiagrams); @@ -223,7 +264,7 @@ public class Standalone { } private void processElements(String path, Consumer operation) throws Exception { - TDLHelper.resetResourceSet(); +// TDLHelper.resetResourceSet(); processElements(path, sourceExtension, operation); } @@ -240,9 +281,9 @@ public class Standalone { if (extension.contains("tdl")) { Files.walk(Path.of(path)) .filter(e->e.getFileName().toString().endsWith(extension)) - .forEach(e->TDLHelper.load(e.toAbsolutePath().toString())); - TDLHelper.link(); - TDLHelper.check(); + .forEach(e->ResourceHandler.load(e.toAbsolutePath().toString())); + ResourceHandler.link(); + ResourceHandler.check(); } Files.walk(Path.of(path)) .filter(e->e.getFileName().toString().endsWith(extension)) @@ -260,10 +301,10 @@ public class Standalone { if (extension.contains("tdl")) { for (File f : files) { System.out.println("Loading: "+f.getAbsolutePath()); - TDLHelper.load(f.getAbsolutePath()); + ResourceHandler.load(f.getAbsolutePath()); } - TDLHelper.link(); - TDLHelper.check(); + ResourceHandler.link(); + ResourceHandler.check(); } for (File f : files) { System.out.println("Processing: "+f.getAbsolutePath()); @@ -272,9 +313,9 @@ public class Standalone { } else { if (extension.contains("tdl")) { System.out.println("Loading: "+target.getAbsolutePath()); - TDLHelper.load(target.getAbsolutePath()); - TDLHelper.link(); - TDLHelper.check(); + ResourceHandler.load(target.getAbsolutePath()); + ResourceHandler.link(); + ResourceHandler.check(); } System.out.println("Processing: "+target.getAbsolutePath()); operation.accept(target.getAbsolutePath()); @@ -282,7 +323,7 @@ public class Standalone { } private void listElements(String path) { - Resource resource = TDLHelper.load(path); + Resource resource = ResourceHandler.load(path); Package p = (Package) resource.getContents().get(0); System.out.println("Package: "+p.getName()); p.getNestedPackage().forEach(e -> { @@ -305,27 +346,27 @@ public class Standalone { } private void validate(String path) { - Resource resource = TDLHelper.load(path); - Validator validator = new Validator(); + Resource resource = ResourceHandler.load(path); +// Validator validator = new Validator(); //TODO: make robust against unresolved imports //TODO: report parsing / resolution errors - try { - List violations = validator.validate(resource); - validator.dumpViolations(violations, true); - } catch (Exception e) { - e.printStackTrace(); - } +// try { +// List violations = validator.validate(resource); +// validator.dumpViolations(violations, true); +// } catch (Exception e) { +// e.printStackTrace(); +// } } private void validateOCL(String path) { - Resource resource = TDLHelper.load(path); - Validator validator = new Validator(); - validator.validateOCL2(resource); + Resource resource = ResourceHandler.load(path); +// Validator validator = new Validator(); +// validator.validateOCL2(resource); } private void evaluateOCLInline(String path) { - Resource resource = TDLHelper.load(path); - OCL ocl = OCL.newInstance(TDLHelper.getResourceSet()); + Resource resource = ResourceHandler.load(path); + OCL ocl = OCL.newInstance(ResourceHandler.getResourceSet()); EClass contextEClass = tdlPackage.Literals.GATE_TYPE; try { ExpressionInOCL query = ocl.createQuery(contextEClass, @@ -343,11 +384,11 @@ public class Standalone { } private void translate(String path) { - Resource resource = TDLHelper.load(path); + Resource resource = ResourceHandler.load(path); try { - Resource target = TDLHelper.create(resource.getURI().path() + "." + targetExtension); + Resource target = ResourceHandler.create(resource.getURI().path() + "." + targetExtension); target.getContents().addAll(EcoreUtil.copyAll(resource.getContents())); - TDLHelper.store(target, true); + ResourceHandler.store(target, true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -357,10 +398,10 @@ public class Standalone { private void importData(String path, AbstractTranslator translator) { File source = new File(path); try { - translator.setTargetResource(TDLHelper.create(source.getAbsolutePath()+"-generated."+targetExtension)); + translator.setTargetResource(ResourceHandler.create(source.getAbsolutePath()+"-generated."+targetExtension)); translator.initTargetResource(translator.cleanName(source.getName())); translator.translate(source.getAbsolutePath()); - TDLHelper.store(translator.getTargetResource(), true); + ResourceHandler.store(translator.getTargetResource(), false); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -385,7 +426,7 @@ public class Standalone { } private void generateDiagrams(String path) { - Resource resource = TDLHelper.load(path); + Resource resource = ResourceHandler.load(path); //export to external generator EObject model = resource.getContents().get(0); generateConfiguration(path, model); @@ -566,18 +607,22 @@ public class Standalone { importData(path, new ASN2TDLTranslator()); } + private void importYANG(String path) { + importData(path, new Yang2TDLTranslator()); + } + private void importJSON(String path) { importData(path, new JSON2TDLTranslator()); } private void exportJSON(String path) { - Resource resource = TDLHelper.load(path); + Resource resource = ResourceHandler.load(path); TDL2JSONTranslator translator = new TDL2JSONTranslator(); translator.transform((Package) resource.getContents().get(0)); } private void exportDoc(String path) { - Resource resource = TDLHelper.load(path); + Resource resource = ResourceHandler.load(path); Generator generator = new Generator(); String target = path+".docx"; try { @@ -595,14 +640,15 @@ public class Standalone { private void exportTTCN3(String path) { try { new TTCN3StandaloneSetup().createInjectorAndDoEMFRegistration(); - Resource resource = TDLHelper.load(path); - Transform transformer = new Transform(); - Resource ir = TDLHelper.create(path+"-generated.ttcn3m"); - transformer.transform(resource, ir); - //This is important otherwise ghost references may occur - ir.unload(); - Resource tr = TDLHelper.create(path+"-generated.ttcn3"); - transformer.transform(resource, tr); + Resource resource = ResourceHandler.load(path); + TTCN3Renderer ttcn3 = new TTCN3Renderer(); + List packages = EcoreUtil2.getAllContentsOfType(resource, Package.class); + for (Package p : packages) { + String output = ""; + output += ttcn3.render(p, " "); + Files.writeString(Path.of(Path.of(path).getParent().toString(), p.getName()+".ttcn3"), output); + + } } catch (Exception e) { e.printStackTrace(); } diff --git a/plugins/org.etsi.mts.tdl.to2tdl/.classpath b/plugins/org.etsi.mts.tdl.to2tdl/.classpath index 685a6999c9acba0d0158b0929d7a4d384644452e..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.to2tdl/.classpath +++ b/plugins/org.etsi.mts.tdl.to2tdl/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.to2tdl/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.to2tdl/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..cc4eaa539c5f4b0f916828ed253989682ceaf93c --- /dev/null +++ b/plugins/org.etsi.mts.tdl.to2tdl/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.to2tdl/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.to2tdl/META-INF/MANIFEST.MF index 09a5cf5f295a648b24fae73ac81cef0e9d5417c1..17caceccc04e33c36bae13357fb4796c97df4504 100644 --- a/plugins/org.etsi.mts.tdl.to2tdl/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.to2tdl/META-INF/MANIFEST.MF @@ -5,13 +5,12 @@ Bundle-SymbolicName: org.etsi.mts.tdl.to2tdl Bundle-Version: 1.0.0.qualifier Automatic-Module-Name: org.etsi.mts.tdl.to2tdl Bundle-Vendor: ETSI +Bundle-Activator: org.etsi.mts.tdl.to2tdl.Activator Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.emf.ecore, org.eclipse.xtext, org.etsi.mts.tdl.model, - org.eclipse.ocl.xtext.essentialocl, - org.etsi.mts.tdl.common, - org.etsi.mts.tdl.helper + org.etsi.mts.tdl.common Export-Package: org.etsi.mts.tdl.to2tdl -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 diff --git a/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/Activator.java b/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/Activator.java new file mode 100644 index 0000000000000000000000000000000000000000..d0f16df59aa7b1e8d274d641a977558abe539865 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/Activator.java @@ -0,0 +1,60 @@ +package org.etsi.mts.tdl.to2tdl; + +import java.util.Hashtable; + +import org.etsi.mts.tdl.transform.AbstractTranslator; +import org.etsi.mts.tdl.transform.Converter; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +//public class Activator extends Plugin { +public class Activator implements BundleActivator { + + // The plug-in ID + public static final String PLUGIN_ID = "org.etsi.mts.tdl.to2tdl"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { +// super.start(context); + Hashtable properties = new Hashtable(); + properties.put("type", PLUGIN_ID); + context.registerService(Converter.class.getName(), new TO2TDLConverter(), properties); + context.registerService(AbstractTranslator.class.getName(), new TO2TDLTranslator(), properties); + //TODO: extract to enum? interface? + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; +// super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/TO2TDLConverter.java b/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/TO2TDLConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..85ee4952e351f0c9f2ec23fc71d6fd34c18a8268 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/TO2TDLConverter.java @@ -0,0 +1,58 @@ +package org.etsi.mts.tdl.to2tdl; + +import java.io.File; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.etsi.mts.tdl.transform.AbstractTranslator; +import org.etsi.mts.tdl.transform.Converter; + +import org.etsi.mts.tdl.Package; +import org.etsi.mts.tdl.resources.ResourceHandler; + +public class TO2TDLConverter implements Converter { + + public String processToString(String inputPath, String outputPath) { + return processToString(inputPath, outputPath, "SOURCE_MAPPING", "TARGET_MAPPING"); + } + + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) { + return processToString(inputPath, outputPath, sourceMapping, targetMapping, false); + } + + public String getTargetPackageName(String inputPath) { + return AbstractTranslator.cleanName(new File(inputPath).getName()); + } + + public String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping, boolean inline) { +// OpenAPI spec = parseSpec(inputPath); + System.out.println("Exporting: "+outputPath+ " : "+ new File(outputPath).getAbsolutePath()); + TO2TDLTranslator translator = new TO2TDLTranslator(); + String content = "Package imported {}"; + //TODO: This is effectively broken.. + try { + URI uri = URI.createPlatformResourceURI(inputPath, true); + Resource r = ResourceHandler.getResourceSet().getResource(uri, true); + Package p = (Package) r.getContents().get(0); + Resource tr = ResourceHandler.create(outputPath); + translator.setTargetResource(tr); + translator.initTargetResource(getTargetPackageName(inputPath)); + translator.initTargetResource("generated_from_"+p.getName()); + translator.addImports(p); + translator.transform(p); + EcoreUtil.resolveAll(tr); + content = ResourceHandler.getText(tr); + } catch (Exception e) { + e.printStackTrace(); + } + return content; + } + + @Override + public String getExtension() { + // TODO Auto-generated method stub + return "tplan2"; + } + +} diff --git a/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/TO2TDLTranslator.java b/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/TO2TDLTranslator.java index ee7fc34a652c46a822bc7d65b42be60e426355cf..9bfc9dcc0fc0f857d9f8beb2b8ea55d3dabb8951 100644 --- a/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/TO2TDLTranslator.java +++ b/plugins/org.etsi.mts.tdl.to2tdl/src/org/etsi/mts/tdl/to2tdl/TO2TDLTranslator.java @@ -6,7 +6,9 @@ import java.util.Set; import java.util.stream.Collectors; import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.etsi.mts.tdl.Comment; @@ -29,7 +31,7 @@ import org.etsi.mts.tdl.TestConfiguration; import org.etsi.mts.tdl.TestDescription; import org.etsi.mts.tdl.tdlFactory; import org.etsi.mts.tdl.tdlPackage; -import org.etsi.mts.tdl.helper.TDLHelper; +import org.etsi.mts.tdl.resources.ResourceHandler; import org.etsi.mts.tdl.structuredobjectives.Content; import org.etsi.mts.tdl.structuredobjectives.DataReference; import org.etsi.mts.tdl.structuredobjectives.EntityReference; @@ -468,13 +470,23 @@ public class TO2TDLTranslator extends AbstractTranslator { @Override public void translate(String filename) throws Exception { - Resource sr = TDLHelper.load(filename); - Resource tr = TDLHelper.create(filename+"_generated.tdltx"); - Package p = (Package) sr.getContents().get(0); - setTargetResource(tr); - initTargetResource("generated_from_"+p.getName()); - addImports(p); - transform(p); - TDLHelper.store(tr, false); +// Resource sr = TDLHelper.load(filename); +// Resource tr = TDLHelper.create(filename+"_generated.tdltx"); +// Package p = (Package) sr.getContents().get(0); +// setTargetResource(tr); +// initTargetResource("generated_from_"+p.getName()); +// addImports(p); +// transform(p); +// TDLHelper.store(tr, false); + try { + URI uri = URI.createPlatformResourceURI(filename, true); + Resource r = ResourceHandler.getResourceSet().getResource(uri, true); + Package p = (Package) r.getContents().get(0); + transform(p); + EcoreUtil.resolveAll(getTargetResource()); + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/.classpath b/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/.classpath index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/.settings/org.eclipse.jdt.core.prefs index 402051ba9fb8d5fed4ff1a609449b764896e9083..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/META-INF/MANIFEST.MF index 4ec9d9aa53fe060ce6aeebeb9a27a85a6af0d949..11d9d34117a8caacd2b49336aad25fe5db50480f 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.tools.to.docx.poi.ui/META-INF/MANIFEST.MF @@ -1,5 +1,6 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 +Automatic-Module-Name: org.etsi.mts.tdl.tools.to.docx.poi.ui Bundle-Name: Ui Bundle-SymbolicName: org.etsi.mts.tdl.tools.to.docx.poi.ui;singleton:=true Bundle-Version: 1.0.0.qualifier @@ -10,8 +11,7 @@ Require-Bundle: org.eclipse.ui, org.eclipse.ui.editors;bundle-version="3.5.0", org.eclipse.ui.ide;bundle-version="3.5.0", org.eclipse.ui.workbench, - com.google.inject, org.eclipse.xtext.ui, org.etsi.mts.tdl.tools.to.docx.poi -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Bundle-ActivationPolicy: lazy diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.poi/.classpath b/plugins/org.etsi.mts.tdl.tools.to.docx.poi/.classpath index 685a6999c9acba0d0158b0929d7a4d384644452e..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.poi/.classpath +++ b/plugins/org.etsi.mts.tdl.tools.to.docx.poi/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.poi/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.tools.to.docx.poi/.settings/org.eclipse.jdt.core.prefs index 6de43e0b68785ef12f4902276ece57a1275f7bef..23fa13b170502d5a7f7a0549188dbc454a7cf0c8 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.poi/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.tools.to.docx.poi/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,9 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=10 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.poi/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.tools.to.docx.poi/META-INF/MANIFEST.MF index 05827653c48c482f27f16484488d4fdfb82a1742..5bc66730200e7a2c77195c8cf5669cc99e84c2a1 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.poi/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.tools.to.docx.poi/META-INF/MANIFEST.MF @@ -4,22 +4,25 @@ Bundle-Name: TDL-TO to Docx Generation (Apache POI Binding) Bundle-SymbolicName: org.etsi.mts.tdl.tools.to.docx.poi Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.etsi.mts.tdl.tools.to.docx.poi.Activator +Bundle-ClassPath: . Bundle-Vendor: ETSI Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.emf.ecore, org.eclipse.xtext, org.etsi.mts.tdl.model, - org.etsi.mts.tdl.TPLan2, - org.eclipse.emf.mwe.utils, - org.eclipse.ocl.xtext.essentialocl, org.etsi.mts.tdl.common, - org.apache.poi, - org.apache.poi.ooxml, - org.apache.poi.ooxml.schemas, - org.apache.xmlbeans, - org.apache.commons.compress -Bundle-RequiredExecutionEnvironment: JavaSE-11 + org.apache.commons.commons-io, + org.apache.logging.log4j.api, + org.apache.logging.log4j.core, + org.apache.logging.log4j.slf4j2.impl, + org.apache.commons.lang3, + org.apache.commons.commons-collections4, + org.apache.poi;bundle-version="[4.0.0,5.0.0)", + org.apache.poi.ooxml;bundle-version="[4.0.0,5.0.0)", + org.apache.poi.ooxml.schemas;bundle-version="[4.0.0,5.0.0)", + org.apache.xmlbeans +Bundle-RequiredExecutionEnvironment: JavaSE-21 Automatic-Module-Name: org.etsi.mts.tdl.tools.to.docx.poi Bundle-ActivationPolicy: lazy Export-Package: org.etsi.mts.tdl.tools.to.docx.poi diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.poi/src/org/etsi/mts/tdl/tools/to/docx/poi/GeneratorApp.java b/plugins/org.etsi.mts.tdl.tools.to.docx.poi/src/org/etsi/mts/tdl/tools/to/docx/poi/GeneratorApp.java deleted file mode 100644 index 73e317952140b136f1847be994b87f4b58ef957c..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.poi/src/org/etsi/mts/tdl/tools/to/docx/poi/GeneratorApp.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.etsi.mts.tdl.tools.to.docx.poi; - -import java.io.File; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EOperation; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.EValidator; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.ocl.common.OCLConstants; -import org.eclipse.ocl.pivot.internal.delegate.OCLInvocationDelegateFactory; -import org.eclipse.ocl.pivot.internal.delegate.OCLSettingDelegateFactory; -import org.eclipse.ocl.pivot.internal.delegate.OCLValidationDelegateFactory; -import org.eclipse.ocl.xtext.essentialocl.EssentialOCLStandaloneSetup; -import org.eclipse.xtext.resource.XtextResource; -import org.eclipse.xtext.resource.XtextResourceSet; -import org.etsi.mts.tdl.TPLan2StandaloneSetup; -import org.etsi.mts.tdl.impl.tdlPackageImpl; -import org.etsi.mts.tdl.structuredobjectives.impl.StructuredObjectivesPackageImpl; - -import com.google.inject.Injector; - -public class GeneratorApp { - - public static void main(String[] args) { - Generator generator = new Generator(); - try { - String filename = args[0]; - init(); - Resource resource = load(filename); - File file = new File(filename); - String target = file.getName()+".docx"; - generator.generate(resource, target, "TEST-RESOURCE"); - - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public static void init() { - tdlPackageImpl.init(); - StructuredObjectivesPackageImpl.init(); - EssentialOCLStandaloneSetup.doSetup(); - initializeValidator(); - } - - public static Resource load(String filename) { - new org.eclipse.emf.mwe.utils.StandaloneSetup().setPlatformUri("../"); - Injector injector = new TPLan2StandaloneSetup().createInjectorAndDoEMFRegistration(); - XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class); - resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE); - Resource resource = resourceSet.getResource(URI.createURI(filename), true); - return resource; - } - - public static void initializeValidator() { - // OCL.initialize(null); - String oclDelegateURI = OCLConstants.OCL_DELEGATE_URI+"/Pivot"; - - EOperation.Internal.InvocationDelegate.Factory.Registry.INSTANCE.put(oclDelegateURI, - new OCLInvocationDelegateFactory(oclDelegateURI)); - EStructuralFeature.Internal.SettingDelegate.Factory.Registry.INSTANCE.put(oclDelegateURI, - new OCLSettingDelegateFactory(oclDelegateURI)); - EValidator.ValidationDelegate.Registry.INSTANCE.put(oclDelegateURI, - new OCLValidationDelegateFactory(oclDelegateURI)); - - // EStructuralFeature.Internal.SettingDelegate.Factory.Registry.INSTANCE.put(oclDelegateURI, - // new OCLSettingDelegateFactory.Global()); - // QueryDelegate.Factory.Registry.INSTANCE.put(oclDelegateURI, new OCLQueryDelegateFactory.Global()); - - } - - -} diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/.classpath b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/.classpath deleted file mode 100644 index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/.gitignore b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/.gitignore deleted file mode 100644 index d027396de4e400df918ced333285b6dd893b9fb0..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/.settings/ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/META-INF/MANIFEST.MF deleted file mode 100644 index edaecbf8d666d56d6bcbb8b5b6530c06f70569ea..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/META-INF/MANIFEST.MF +++ /dev/null @@ -1,18 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: Ui -Bundle-SymbolicName: org.etsi.mts.tdl.tools.to.docx.ui;singleton:=true -Bundle-Version: 1.0.0.qualifier -Bundle-Activator: org.etsi.mts.tdl.tools.to.docx.ui.Activator -Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime, - org.eclipse.core.resources, - org.eclipse.ui.editors;bundle-version="3.5.0", - org.eclipse.ui.ide;bundle-version="3.5.0", - org.eclipse.ui.workbench, - com.google.inject, - org.eclipse.xtext.ui, - org.etsi.mts.tdl.model, - org.etsi.mts.tdl.tools.to.docx -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Bundle-ActivationPolicy: lazy diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/build.properties b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/build.properties deleted file mode 100644 index 6f4455d0e120b77b0904d2835d63f30dcde30b90..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/build.properties +++ /dev/null @@ -1,6 +0,0 @@ -source.. = src/ -output.. = target/classes/ -bin.includes = plugin.xml,\ - META-INF/,\ - .,\ - icons/ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/icons/WordIcon.png b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/icons/WordIcon.png deleted file mode 100644 index 3eccc1ca0d8d61166446b4ff64f1c24f4a846e0a..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/icons/WordIcon.png and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/icons/sample.gif b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/icons/sample.gif deleted file mode 100644 index 34fb3c9d8cb7d489681b7f7aee4bdcd7eaf53610..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/icons/sample.gif and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/plugin.xml b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/plugin.xml deleted file mode 100644 index 822696be8044a0cf7e28642db3ab37a6a9e72bb4..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/plugin.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/pom.xml b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/pom.xml deleted file mode 100644 index f50e6029e32451c553697627f36c3c1cf9ce40d2..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - 4.0.0 - - org.etsi.mts.tdl - org.etsi.mts.tdl.parent - 1.0.0-SNAPSHOT - ../../org.etsi.mts.tdl.parent - - - org.etsi.mts.tdl.tools.to.docx.ui - eclipse-plugin - - - - maven-compiler-plugin - - - - \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/handlers/.project b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/handlers/.project deleted file mode 100644 index b6e59aeba9ddff4fee3c1a4e3e4589e2703bb2cd..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/handlers/.project +++ /dev/null @@ -1 +0,0 @@ -DUMMY \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/handlers/GenerationHandler.java b/plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/handlers/GenerationHandler.java deleted file mode 100644 index b3eb63874a35a526e0b4d25032aa72199016ddb1..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx.ui/src/org/etsi/mts/tdl/tools/to/docx/ui/handlers/GenerationHandler.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.etsi.mts.tdl.tools.to.docx.ui.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; -import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.xtext.ui.resource.IResourceSetProvider; -import org.etsi.mts.tdl.tools.to.docx.TemplateApp; -import com.google.inject.Inject; - -/** - * Our sample handler extends AbstractHandler, an IHandler base class. - * @see org.eclipse.core.commands.IHandler - * @see org.eclipse.core.commands.AbstractHandler - */ -public class GenerationHandler extends AbstractHandler { - @Inject - IResourceSetProvider resourceSetProvider; - - private IWorkbenchWindow window; - - /** - * The constructor. - */ - public GenerationHandler() { - } - - /** - * the command has been executed, so extract extract the needed information - * from the application context. - */ - public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getCurrentSelection(event); - IEditorInput input = HandlerUtil.getActiveEditorInput(event); - IFile file = null; - IProject project = null; - if (input != null && input instanceof FileEditorInput) { - file = ((FileEditorInput) input).getFile(); - project = file.getProject(); - } else if (selection !=null && selection instanceof IStructuredSelection) { - IStructuredSelection structuredSelection = (IStructuredSelection) selection; - Object firstElement = structuredSelection.getFirstElement(); - if (firstElement instanceof IFile) { - file = (IFile) firstElement; - project = file.getProject(); - } - } - - if (file !=null) { - URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); - ResourceSet rs = new ResourceSetImpl(); - Resource r = rs.getResource(uri, true); - TemplateApp app = new TemplateApp(); - app.inlineEventOccurrenceTemplates(r); - app.attachSources(r); - //app.setTemplateName(templateName); - app.generate(file.getRawLocation().toOSString(), r); - } - MessageDialog.openInformation( - Display.getDefault().getActiveShell(), -// window.getShell(), - "Generating Document", - "Document generated: "+file.getName()); - - return null; - } - public void init(IWorkbenchWindow window) { - this.window = window; - } - - @Override - public boolean isEnabled() { - return true; - } -} diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/.classpath b/plugins/org.etsi.mts.tdl.tools.to.docx/.classpath deleted file mode 100644 index 49b9e43e079148598748d91ee49b0dd5cb43fd3a..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/.classpath +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/.gitignore b/plugins/org.etsi.mts.tdl.tools.to.docx/.gitignore deleted file mode 100644 index d027396de4e400df918ced333285b6dd893b9fb0..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/.settings/ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.tools.to.docx/META-INF/MANIFEST.MF deleted file mode 100644 index 227774f7ff0a5bf3cc752db3f56fe5c5c79860ed..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/META-INF/MANIFEST.MF +++ /dev/null @@ -1,18 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: TO Word Export (deprecated docx4j Binding) -Bundle-SymbolicName: org.etsi.mts.tdl.tools.to.docx -Bundle-Version: 1.0.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.core.runtime, - org.eclipse.xtext, - org.eclipse.ocl.common, - org.eclipse.ocl.ecore, - org.etsi.mts.tdl.model, - org.eclipse.swt, - org.eclipse.xtext.ui, - org.etsi.mts.tdl.TPLan2.ui, - org.etsi.mts.tdl.TPLan2 -Export-Package: org.etsi.mts.tdl.tools.to.docx -Bundle-ClassPath: ., - lib/docx4j-1.0-jar-with-dependencies.jar diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplates.docx b/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplates.docx deleted file mode 100644 index 41dead6d51d94aa755f4d5083e398524ed55e871..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplates.docx and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR.docx b/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR.docx deleted file mode 100644 index effc5b8e960c4cf6cbb732f6d54570186b5b80b7..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR.docx and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR1.docx b/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR1.docx deleted file mode 100755 index cd2d143d0d0261e2b23b8827ee96364e9619a214..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR1.docx and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR2.docx b/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR2.docx deleted file mode 100644 index bdbdf0f2622669b1ed520256a4c8250a2346254f..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/TO_TableTemplatesR2.docx and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/build.properties b/plugins/org.etsi.mts.tdl.tools.to.docx/build.properties deleted file mode 100644 index 2ef4e6f3b4ea335d3a2e39c9bcc54f0093995d88..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/build.properties +++ /dev/null @@ -1,9 +0,0 @@ -source.. = src/ -output.. = target/classes/ -bin.includes = META-INF/,\ - .,\ - TO_TableTemplatesR1.docx,\ - empty.docx,\ - lib/docx4j-1.0-jar-with-dependencies.jar -src.includes = TO_TableTemplatesR1.docx,\ - empty.docx diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/empty.docx b/plugins/org.etsi.mts.tdl.tools.to.docx/empty.docx deleted file mode 100644 index 43ea13838539518a578c7f8177d5b41175aabd45..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/empty.docx and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/docx4j-3.2.1.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/docx4j-3.2.1.jar deleted file mode 100644 index 5d07f6b6f3236b861ffd7896dd1acc7e539620cc..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/docx4j-3.2.1.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/jaxb-xmldsig-core-1.0.0.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/jaxb-xmldsig-core-1.0.0.jar deleted file mode 100644 index 35572143dcf88a9ca5c740a9635ceee477a3c30f..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/jaxb-xmldsig-core-1.0.0.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/jaxb-xslfo-1.0.1.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/jaxb-xslfo-1.0.1.jar deleted file mode 100644 index 3db099d6428eba24f97b950789da1715f1c2e4bb..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/jaxb-xslfo-1.0.1.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/log4j-1.2.17.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/log4j-1.2.17.jar deleted file mode 100644 index 068867ebfd231db09a7775794eea8127420380ed..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/log4j-1.2.17.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/serializer.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/serializer.jar deleted file mode 100644 index 10c881c100ebd5ecd9ffb5ba912711f667169a76..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/serializer.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/slf4j-api-1.7.12.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/slf4j-api-1.7.12.jar deleted file mode 100644 index e357ddc7fd27dfec1e6347d39a013348f443ec55..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/slf4j-api-1.7.12.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/slf4j-log4j12-1.7.12.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/slf4j-log4j12-1.7.12.jar deleted file mode 100644 index 8035e08cce3bfad3749117c8195ad1ba4a2763b7..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/slf4j-log4j12-1.7.12.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xalan.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xalan.jar deleted file mode 100644 index abdabe33ec1368f910ac7012f081ad2ae9e4897b..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xalan.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xercesImpl.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xercesImpl.jar deleted file mode 100644 index 0aaa990f3ecadf60d28b5395dc87bbe49da0cdd7..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xercesImpl.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xml-apis.jar b/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xml-apis.jar deleted file mode 100644 index 46733464fc746776c331ecc51061f3a05e662fd1..0000000000000000000000000000000000000000 Binary files a/plugins/org.etsi.mts.tdl.tools.to.docx/lib/xml-apis.jar and /dev/null differ diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/src/docx4j.properties b/plugins/org.etsi.mts.tdl.tools.to.docx/src/docx4j.properties deleted file mode 100644 index df77b3944487470890f701162362a36877a8db65..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/src/docx4j.properties +++ /dev/null @@ -1,30 +0,0 @@ -# Page size: use a value from org.docx4j.model.structure.PageSizePaper enum -# eg A4, LETTER -docx4j.PageSize=LETTER -# Page size: use a value from org.docx4j.model.structure.MarginsWellKnown enum -docx4j.PageMargins=NORMAL -docx4j.PageOrientationLandscape=false - -# Page size: use a value from org.pptx4j.model.SlideSizesWellKnown enum -# eg A4, LETTER -pptx4j.PageSize=LETTER -pptx4j.PageOrientationLandscape=false - -# These will be injected into docProps/app.xml -# if App.Write=true -docx4j.App.write=true -docx4j.Application=docx4j -docx4j.AppVersion=2.7 -# of the form XX.YYYY where X and Y represent numerical values - -# These will be injected into docProps/core.xml -docx4j.dc.write=true -docx4j.dc.creator.value=docx4j -docx4j.dc.lastModifiedBy.value=docx4j - -# -#docx4j.McPreprocessor=true - -# If you haven't configured log4j yourself -# docx4j will autoconfigure it. Set this to true to disable that -docx4j.Log4j.Configurator.disabled=false diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/src/log4j.properties b/plugins/org.etsi.mts.tdl.tools.to.docx/src/log4j.properties deleted file mode 100644 index 4404dbcb16a95486f76c0cf00064d490efe8e1a8..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/src/log4j.properties +++ /dev/null @@ -1,4 +0,0 @@ -log4j.rootLogger=WARN, console -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.conversionPattern=%5p [%t] (%F:%L) - %m%n diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/src/log4j.xml b/plugins/org.etsi.mts.tdl.tools.to.docx/src/log4j.xml deleted file mode 100644 index 08678580f4bb90c68fdf1952708f140523dddf8e..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/src/log4j.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/src/org/etsi/mts/tdl/tools/to/docx/TemplateApp.java b/plugins/org.etsi.mts.tdl.tools.to.docx/src/org/etsi/mts/tdl/tools/to/docx/TemplateApp.java deleted file mode 100644 index 041c1de848d90039b9b0ef7bdfd8047d6a25e63b..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/src/org/etsi/mts/tdl/tools/to/docx/TemplateApp.java +++ /dev/null @@ -1,397 +0,0 @@ -package org.etsi.mts.tdl.tools.to.docx; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.docx4j.openpackaging.exceptions.Docx4JException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.xtext.EcoreUtil2; -import org.eclipse.xtext.nodemodel.ICompositeNode; -import org.eclipse.xtext.nodemodel.util.NodeModelUtils; -import org.eclipse.xtext.serializer.impl.Serializer; -import org.etsi.mts.tdl.Annotation; -import org.etsi.mts.tdl.AnnotationType; -import org.etsi.mts.tdl.Comment; -import org.etsi.mts.tdl.Element; -import org.etsi.mts.tdl.structuredobjectives.EntityBinding; -import org.etsi.mts.tdl.structuredobjectives.EntityReference; -import org.etsi.mts.tdl.structuredobjectives.Event; -import org.etsi.mts.tdl.structuredobjectives.EventOccurrence; -import org.etsi.mts.tdl.structuredobjectives.EventOccurrenceSpecification; -import org.etsi.mts.tdl.structuredobjectives.EventReference; -import org.etsi.mts.tdl.structuredobjectives.EventSequence; -import org.etsi.mts.tdl.structuredobjectives.EventTemplateOccurrence; -import org.etsi.mts.tdl.structuredobjectives.ExpectedBehaviour; -import org.etsi.mts.tdl.structuredobjectives.InitialConditions; -import org.etsi.mts.tdl.structuredobjectives.PICSReference; -import org.etsi.mts.tdl.Package; -import org.etsi.mts.tdl.TPLan2StandaloneSetup; -import org.etsi.mts.tdl.TimeConstraint; -import org.etsi.mts.tdl.tdlFactory; -import org.etsi.mts.tdl.structuredobjectives.StructuredTestObjective; -import org.osgi.framework.Bundle; - -import java.util.logging.Logger; - -import com.google.inject.Injector; - -public class TemplateApp { - - private WordTemplateTestObjective wordTemplateExporter; - private String templateName = - "TO_1_TABLE_TEMPLATE" -// "TO_2_TABLE_TEMPLATE" -// "TO_3_TABLE_TEMPLATE_ONEM2M" - ; - protected static Logger log; - protected Injector injector; - private boolean filterKeywords = true; - private String templateFileName = "TO_TableTemplates.docx"; - public static boolean inlineEventOccurrenceTemplates = true; - - public void generate(String inputPath, Package p) { - templateFileName = "TO_TableTemplatesR1.docx"; - String outputPath = new File(inputPath).getParentFile().getAbsolutePath(); - String fileName = new File(inputPath).getName(); - try { - process(p, outputPath+"/"+fileName+".docx"); - } catch (Docx4JException e) { - e.printStackTrace(); - } - } - - public void generate(String inputPath, Resource r) { - templateFileName = "TO_TableTemplatesR1.docx"; - String outputPath = new File(inputPath).getParentFile().getAbsolutePath(); - String fileName = new File(inputPath).getName(); - try { - for (EObject o : r.getContents()) { - process((Package)o, outputPath+"/"+fileName+".docx"); - } - } catch (Docx4JException e) { - e.printStackTrace(); - } - } - - public void attachSources(Resource resource) { - Package packageContainer = (Package) resource.getContents().get(0); - - Package predefined = tdlFactory.eINSTANCE.createPackage(); - predefined.setName("PREDEFINED"); - packageContainer.getNestedPackage().add(predefined); - AnnotationType source = tdlFactory.eINSTANCE.createAnnotationType(); - source.setName("SOURCE"); - predefined.getPackagedElement().add(source); - - List describedElements = new ArrayList(); - describedElements.addAll(EcoreUtil2.getAllContentsOfType(packageContainer, InitialConditions.class)); - describedElements.addAll(EcoreUtil2.getAllContentsOfType(packageContainer, ExpectedBehaviour.class)); - describedElements.addAll(EcoreUtil2.getAllContentsOfType(packageContainer, EventSequence.class)); -// describedElements.addAll(EcoreUtil2.getAllContentsOfType(packageContainer, Event.class)); -// describedElements.addAll(EcoreUtil2.getAllContentsOfType(packageContainer, TimeConstraint.class)); -// describedElements.addAll(EcoreUtil2.getAllContentsOfType(packageContainer, EventReference.class)); - for (Element e : describedElements) { - ICompositeNode node = NodeModelUtils.getNode(e); - Annotation a = tdlFactory.eINSTANCE.createAnnotation(); - a.setKey(source); - String text = node.getText(); - text = text.replaceAll("\t", " "); - String indent = getIndent(text, 1); - text = text.trim(); - text = text.replaceAll("\n"+indent, "\n"); - a.setValue(text); - e.getAnnotation().add(a); - } - } - - public String getIndent(String s, int start) - { - - int limit = s.length(); - int i = start; - - for (; i < limit; i++) - { - if (!String.valueOf(s.charAt(i)).equals(" ")) - { - break; - } - } - - return s.substring(start, i); - } - - - public String serialise(EObject o) { - Injector injector = new TPLan2StandaloneSetup().createInjectorAndDoEMFRegistration(); - String s = ""; - Serializer serializer = injector.getInstance(Serializer.class); - - try { - s += serializer.serialize(o); - } catch (Exception ex) { // fall back: - System.out.println("Object could not be serialized"); - System.out.println(ex.getMessage()); - ex.printStackTrace(); - } - - return s; - } - - - public void inlineEventOccurrenceTemplates(Resource r) { - for (EObject o : r.getContents()) { - inlineEventOccurrenceTemplates((Package)o); - } - } - - public void inlineEventOccurrenceTemplates(Package p) { - List eSequences = EcoreUtil2.getAllContentsOfType(p, EventSequence.class); - for (EventSequence es : eSequences) { - for (EventOccurrence eo : es.getEvents()) { - if (eo instanceof EventTemplateOccurrence) { - EventOccurrenceSpecification eSpec = ((EventTemplateOccurrence) eo).getEventTemplate().getEventSpecification(); - int i = es.getEvents().indexOf(eo); - EventOccurrenceSpecification templateOccurrence = EcoreUtil.copy(eSpec); - for (Comment c : eo.getComment()) { - templateOccurrence.getComment().add(EcoreUtil.copy(c)); - } - if (((EventTemplateOccurrence) eo).getOccurrenceArgument() != null) { - templateOccurrence.setEventArgument(((EventTemplateOccurrence) eo).getOccurrenceArgument()); - } - if (!((EventTemplateOccurrence) eo).getEntityBinding().isEmpty()) { - for (EntityBinding b : ((EventTemplateOccurrence) eo).getEntityBinding()) { - EntityReference occurrenceEntity = b.getOccurrenceEntity(); - if ((b.getTemplateEntity().getEntity() !=null - && templateOccurrence.getEntityReference().getEntity() != null - && b.getTemplateEntity().getEntity().equals(templateOccurrence.getEntityReference().getEntity())) - || - (b.getTemplateEntity().getComponent() !=null - && templateOccurrence.getEntityReference().getComponent() != null - && b.getTemplateEntity().getComponent().equals(templateOccurrence.getEntityReference().getComponent())) - ) { - templateOccurrence.setEntityReference(occurrenceEntity); - } - //TODO: also compare qualifiers? - //TODO: handle component references - for (EntityReference er : templateOccurrence.getOppositeEntityReference()) { - if ((b.getTemplateEntity().getEntity() !=null - && er.getEntity() !=null - && b.getTemplateEntity().getEntity().equals(er.getEntity())) - || - (b.getTemplateEntity().getComponent() !=null - && er.getComponent() !=null - && b.getTemplateEntity().getComponent().equals(er.getComponent())) - ) { - int oi = templateOccurrence.getOppositeEntityReference().indexOf(er); - templateOccurrence.getOppositeEntityReference().set(oi, occurrenceEntity); - } - } - } - } - es.getEvents().set(i, templateOccurrence); - } - } - } - } - - - public void process(Package p, String outputPath) throws Docx4JException { - wordTemplateExporter = new WordTemplateTestObjective(); - //TODO: make user accessible, safe, and configurable - Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.tools.to.docx"); - String template = bundle.getLocation().substring(15)+templateFileName; - String empty = bundle.getLocation().substring(15)+wordTemplateExporter.getInputFileName(); - try { - template = org.eclipse.core.runtime.FileLocator.toFileURL(bundle.getEntry(templateFileName)).getPath(); - empty = org.eclipse.core.runtime.FileLocator.toFileURL(bundle.getEntry("empty.docx")).getPath(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - wordTemplateExporter.setTemplateFileName(template); - wordTemplateExporter.setInputFileName(empty); - wordTemplateExporter.init(); - setTemplateName("TO_4_TABLE_TEMPLATE_EDITHELP"); - wordTemplateExporter.selectTemplateTable(getTemplateName()); - - List toList = EcoreUtil2.getAllContentsOfType(p, StructuredTestObjective.class); - for (StructuredTestObjective to : toList) { - makeTable(to); - } - - wordTemplateExporter.writeDocumentToFile(outputPath); - } - public void makeTable(StructuredTestObjective to) throws Docx4JException { - wordTemplateExporter.createNewTableFromSelectedTemplate(); - - List toNmLabelStrList = new ArrayList<>(); - List toConfLabelStrList = new ArrayList<>(); - List toDescrLabelStrList = new ArrayList<>(); - List toURIofObjectiveLabelStrList = new ArrayList<>(); - List toPICSselectionLabelStrList = new ArrayList<>(); - List toInitialConditionLabelStrList = new ArrayList<>(); - List toExpectedBehaviourLabelStrList = new ArrayList<>(); - List toWhenLabelStrList = new ArrayList<>(); - List toThenLabelStrList = new ArrayList<>(); - List toFinalBehaviourLabelStrList = new ArrayList<>(); - List whenDirect = new ArrayList<>(); - List thenDirect = new ArrayList<>(); - - toNmLabelStrList.add(to.getName()); - String description = to.getDescription().replaceAll("(\\s)+", " "); - description = description.replaceAll("\"", ""); - toDescrLabelStrList.add(description); - - String e = " "; - if (to.getObjectiveURI().isEmpty()) { - toURIofObjectiveLabelStrList.add(e); - } else { - for (String u : to.getObjectiveURI()) { - u = u.replaceAll("\"", ""); - toURIofObjectiveLabelStrList.add(u); - } - } - - if (to.getPicsReference().isEmpty()) { - toPICSselectionLabelStrList.add(e); - } else { - String l = ""; - for (PICSReference p : to.getPicsReference()) { - if (p.getComment().size()>0) { - l+=" "+p.getComment().get(0).getBody() + " "; - } - - l+= p.getPics().getName(); - } - toPICSselectionLabelStrList.add(l); - } - - String indent = " "; - if (to.getInitialConditions() != null) { - toInitialConditionLabelStrList.add("with {"); - toInitialConditionLabelStrList.addAll(getSequenceSource(to.getInitialConditions().getConditions(), indent)); - toInitialConditionLabelStrList.add("}"); - } else { - toInitialConditionLabelStrList.add(e); - } - - if (to.getExpectedBehaviour() != null) { - toExpectedBehaviourLabelStrList.add("ensure that {"); - String i = indent; - if (to.getExpectedBehaviour().getWhenClause().getEvents().size()>0) { - i=indent+indent; - } - List whenSource = getSequenceSource(to.getExpectedBehaviour().getWhenClause(), indent); - if (whenSource.size()>0) { - toWhenLabelStrList.add(indent+"when {"); - toWhenLabelStrList.addAll(whenSource); - toWhenLabelStrList.add(indent+"}"); - } - List thenSource = getSequenceSource(to.getExpectedBehaviour().getThenClause(), indent); - if (whenSource.size()>0) { - toThenLabelStrList.add(indent+"then {"); - toThenLabelStrList.addAll(thenSource); - toThenLabelStrList.add(indent+"}"); - } else { - toExpectedBehaviourLabelStrList.addAll(thenSource); - } - toExpectedBehaviourLabelStrList.addAll(toWhenLabelStrList); - toExpectedBehaviourLabelStrList.addAll(toThenLabelStrList); - toExpectedBehaviourLabelStrList.add("}"); - } else { - toExpectedBehaviourLabelStrList.add(e); - } - - if (to.getFinalConditions() != null) { - toFinalBehaviourLabelStrList.addAll(getSequenceSource(to.getFinalConditions().getConditions(),indent)); - } else { - toFinalBehaviourLabelStrList.add(e); - } - - wordTemplateExporter.substitutePlaceholder(toNmLabelStrList, wordTemplateExporter.NAME); - wordTemplateExporter.substitutePlaceholder(toDescrLabelStrList, wordTemplateExporter.DESCRIPTION); - wordTemplateExporter.substitutePlaceholder(toURIofObjectiveLabelStrList, wordTemplateExporter.URI); - wordTemplateExporter.substitutePlaceholder(toConfLabelStrList, wordTemplateExporter.CONFIGURATION); - wordTemplateExporter.substitutePlaceholder(toPICSselectionLabelStrList, wordTemplateExporter.PICS); - wordTemplateExporter.substitutePlaceholder(toInitialConditionLabelStrList, wordTemplateExporter.INITIAL); - wordTemplateExporter.substitutePlaceholder(toExpectedBehaviourLabelStrList, wordTemplateExporter.EXPECTED); - wordTemplateExporter.substitutePlaceholder(toFinalBehaviourLabelStrList, wordTemplateExporter.FINAL); - wordTemplateExporter.substitutePlaceholder(toWhenLabelStrList, wordTemplateExporter.WHEN); - wordTemplateExporter.substitutePlaceholder(whenDirect, wordTemplateExporter.WHEN_DIRECTION); - wordTemplateExporter.substitutePlaceholder(toThenLabelStrList, wordTemplateExporter.THEN); - wordTemplateExporter.substitutePlaceholder(thenDirect, wordTemplateExporter.THEN_DIRECTION); - - wordTemplateExporter.addWorkingTableToDocument(); - - String EMPTY_STR = ""; - wordTemplateExporter.addParagraphToDocument(EMPTY_STR ); - } - - private List getSequenceSource(EventSequence sequence, String indent) { - List source = new ArrayList<>(); - String s = ""; - boolean hasSourceAnnotations = false; - for (Annotation a : sequence.getAnnotation()) { - if (a.getKey().getName().equals("SOURCE")) { - hasSourceAnnotations = true; - s = a.getValue(); - s = filterSource(s); - //v = v.replaceAll("_","\\\\\\\\_"); - //v = v.replaceAll(" ","~~"); - } - } - if (!hasSourceAnnotations) { - s = serialise(sequence); - s = filterSource(s); - } - - List lines = Arrays.asList(s.split("\n")); - boolean first = true; - for (String line : lines) { - if (line.trim().length() > 0) { - if (first) { - source.add(indent+indent+indent+line); - first = false; - } else { - source.add(line); - } - System.out.println(source.get(source.size()-1)); - } - } - if (source.isEmpty()) { - source.add(" "); - } - return source; - } - - private String filterSource(String s) { - String filtered = s; - if (filterKeywords) { - filtered = filtered.replaceAll("\"in\"", "in"); - filtered = filtered.replaceAll("entity\\s?", ""); - filtered = filtered.replaceAll("\\(literal\\) ",""); - filtered = filtered.replaceAll("\\(predefined\\) ",""); - filtered = filtered.replaceAll("\\(typed\\) ",""); - filtered = filtered.replaceAll("\t"," "); - } - return filtered; - } - - public String getTemplateName() { - return templateName; - } - - public void setTemplateName(String templateName) { - this.templateName = templateName; - } - -} diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/src/org/etsi/mts/tdl/tools/to/docx/WordTemplateTestObjective.java b/plugins/org.etsi.mts.tdl.tools.to.docx/src/org/etsi/mts/tdl/tools/to/docx/WordTemplateTestObjective.java deleted file mode 100644 index aadc2d054daae9db3242a5a37b08fa4245a02d3e..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/src/org/etsi/mts/tdl/tools/to/docx/WordTemplateTestObjective.java +++ /dev/null @@ -1,441 +0,0 @@ -package org.etsi.mts.tdl.tools.to.docx; - - -import org.docx4j.XmlUtils; -import org.docx4j.openpackaging.packages.WordprocessingMLPackage; -import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart; -import org.docx4j.wml.*; -import org.docx4j.jaxb.*; -import org.docx4j.openpackaging.exceptions.Docx4JException; -import org.docx4j.openpackaging.exceptions.InvalidFormatException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -//import javax.xml.bind.JAXBElement; - -public class WordTemplateTestObjective { - - - String NAME = ""; - String DESCRIPTION = ""; - String URI = ""; - String CONFIGURATION = ""; - String PICS = ""; - String INITIAL = ""; - String EXPECTED = ""; - String FINAL = ""; - String WHEN = ""; - String THEN = ""; - - String THEN_DIRECTION = ""; - String WHEN_DIRECTION = ""; - - - private String templateFileName = "TO_TableTemplates.docx"; - private String inputFileName = "empty.docx"; - -// private final String optFieldPrefix = " rows; - Tr templateRow; - - for (Iterator iterator = templateTableList.iterator(); iterator.hasNext();) { - Object tbl = iterator.next(); - List textElements = getAllElementFromObject(tbl, Text.class); - for (Object text : textElements) { - Text textElement = (Text) text; - if (textElement.getValue() != null && textElement.getValue().equals(templateKey)) { - - - selectedTemplateTable = (Tbl) XmlUtils.deepCopy(tbl); // Clone the selected table - - rows = getAllElementFromObject(selectedTemplateTable, Tr.class); - - templateRow = (Tr) rows.get(0); // Get the first table row where the table key is defined - - selectedTemplateTable.getContent().remove(templateRow); - - searchResult = true; - return searchResult; - } - } - } - return searchResult; - } - - - - /** - * Retrieve the list of place holder identifiers of the selected table template. - * @return The list of place holder identifiers - */ - - public List getAllPlaceholders() { - - List placeHolderStrs = new ArrayList<>(); - List paragraphs = getAllElementFromObject(selectedTemplateTable, P.class); - - for (Object p : paragraphs) - { - List texts = getAllElementFromObject(p, Text.class); - for (Object t : texts) - { - Text content = (Text) t; - if (content.getValue().matches("<[a-zA-Z_0-9]+>") ) // Any sequence of word characters enclosed by '<' and '>' characters - { - placeHolderStrs.add(content.getValue()); - } else { - //System.out.println("::"+content.getValue()); - } - } - } - return placeHolderStrs; - } - - - /** - * Get the list of table template identifiers - * @return the list of table template identifiers - */ - public List getTemplateIdentifiers() { - - List tableIds = new ArrayList<>(); - - - for (Iterator iterator = templateTableList.iterator(); iterator.hasNext();) - { - Object tbl = iterator.next(); - List rows = getAllElementFromObject(tbl, Tr.class); - if ( !rows.isEmpty() ) - { - Tr templateRow = (Tr) rows.get(0); // Get the first table row where the table key is defined - List textElements = getAllElementFromObject(templateRow, Text.class); - for (Object text : textElements) - { - Text textElement = (Text) text; - if (textElement.getValue() != null ) - { - tableIds.add(textElement.getValue()); - } - } - } - } - - return tableIds; - } - - - public boolean createNewTableFromSelectedTemplate() { - boolean result = false; - Tbl newTable = new Tbl(); - - if ( selectedTemplateTable != null ) - { - newTable = (Tbl) XmlUtils.deepCopy(selectedTemplateTable); - workingTable = newTable; - result = true; - } - return result; - - } - - public void writeDocumentToFile( String fname ) - { - try { - writeDocxToStream( wordMLPackageTO, fname ); - } catch (IOException | Docx4JException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - - - /** - * Replace the specified placeholder string with the specified text (list of strings). - * @param newText - * @param placeholder - */ - public void substitutePlaceholder( List newText, String placeholder ) { - - - List trows = getAllElementFromObject(workingTable, Tr.class); - P toReplace = null; - - List replaceparagraphs = getAllElementFromObject(workingTable, P.class); - for (Object p : replaceparagraphs) { - List texts = getAllElementFromObject(p, Text.class); - for (Object t : texts) { - Text content = (Text) t; - if (content.getValue().equals(placeholder)) { - toReplace = (P) p; - break; - } - } - } - if (toReplace == null) { - //System.out.println(":: Could not match placeholder " +placeholder); - } - - for (Object tr : trows) - { - Tr tblrow = (Tr) tr; - - List tcells = getAllElementFromObject(tr, Tc.class); - - for (Object tc : tcells) - { - Tc tblcell = (Tc) tc; - - List paragraphs = getAllElementFromObject(tc, P.class); - for (Object p : paragraphs) - { - List texts = getAllElementFromObject(p, Text.class); - for (Object t : texts) - { - Text content = (Text) t; - if (content.getValue().equals(placeholder)) - { - - boolean isNewTextEmpty = false; - if ( newText == null || newText.isEmpty()) - { - newText = Arrays.asList(""); - //isNewTextEmpty = true; - } - - if (!( isNewTextEmpty //&& (placeholder.startsWith(optFieldPrefix)) - ) ) // Placeholder to be replaced with text - { - Iterator iterator = newText.iterator(); - while ( iterator.hasNext() ) - { - P copy = new P(); - copy = (P) XmlUtils.deepCopy(toReplace); - - // replace the text elements from the copy - List copytexts = getAllElementFromObject(copy, Text.class); - if (copytexts.size() > 0) { - Text textToReplace = (Text) copytexts.get(0); - textToReplace.setValue( (String) iterator.next()); - textToReplace.setSpace("preserve"); - } - - tblcell.getContent().add(copy); - - } - tblcell.getContent().remove(0); // Delete original placeholder paragraph - } - else // The replacement text list is empty and the placeholder is an optional field so the table row is deleted.) - { - //workingTable.getContent().remove(tblrow); - } - - } - } - } - } - } - } - - - - - - - - public void addWorkingTableToDocument() { - wordMLPackageTO.getMainDocumentPart().addObject(workingTable); - } - - - public void addParagraphToDocument( String s ) { - org.docx4j.wml.ObjectFactory locfactory = Context.getWmlObjectFactory(); - org.docx4j.wml.P para = locfactory.createP(); - org.docx4j.wml.Text t = locfactory.createText(); - org.docx4j.wml.R run = locfactory.createR(); - - t.setValue( s ); - run.getContent().add(t); - para.getContent().add(run); - this.wordMLPackageTO.getMainDocumentPart().addObject(para); - - } - - - /** - * retrieve a list elements of specified type contained in specified object - * @param obj the object from which to retrieve the type of elements - * @param toSearch - * @return - */ - private static List getAllElementFromObject(Object obj, Class toSearch) { - List result = new ArrayList(); -// if (obj instanceof JAXBElement) obj = ((JAXBElement) obj).getValue(); -// -// if (obj.getClass().equals(toSearch)) -// result.add(obj); -// else if (obj instanceof ContentAccessor) { -// List children = ((ContentAccessor) obj).getContent(); -// for (Object child : children) { -// result.addAll(getAllElementFromObject(child, toSearch)); -// } -// -// } - return result; - } - - - - - /** - * Open the specified template file - */ - private static WordprocessingMLPackage openTemplatesDocument(String name) throws Docx4JException, FileNotFoundException - { - WordprocessingMLPackage template = WordprocessingMLPackage.load(new FileInputStream(new File(name))); - return template; - } - - - - - /** - * Save the modified template to the specified output Word file. - */ - private static void writeDocxToStream(WordprocessingMLPackage template, String target) throws IOException, Docx4JException - { - File f = new File(target); - template.save(f); - } - - - - - - - // Private variables - - public String getTemplateFileName() { - return templateFileName; - } - - - - - public void setTemplateFileName(String templateFileName) { - this.templateFileName = templateFileName; - } - - - - - - - public String getInputFileName() { - return inputFileName; - } - - - - - public void setInputFileName(String inputFileName) { - this.inputFileName = inputFileName; - } - - - - - - - private Tbl selectedTemplateTable; // The orignal selected table template - private Tbl workingTable = null; // The table being modified before added to the output file - - private List templateTableList; - - - private WordprocessingMLPackage wordMLPackageTemplates; // Word document with Table templates - - private StyleDefinitionsPart wordTemplateStylePart; // Style part in the template document - - private Styles templateStyles; - - - private WordprocessingMLPackage wordMLPackageTO = null; // New Word document to be with filled Test Objective tables - - - - - - -} diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/docx4j.properties b/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/docx4j.properties deleted file mode 100644 index df77b3944487470890f701162362a36877a8db65..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/docx4j.properties +++ /dev/null @@ -1,30 +0,0 @@ -# Page size: use a value from org.docx4j.model.structure.PageSizePaper enum -# eg A4, LETTER -docx4j.PageSize=LETTER -# Page size: use a value from org.docx4j.model.structure.MarginsWellKnown enum -docx4j.PageMargins=NORMAL -docx4j.PageOrientationLandscape=false - -# Page size: use a value from org.pptx4j.model.SlideSizesWellKnown enum -# eg A4, LETTER -pptx4j.PageSize=LETTER -pptx4j.PageOrientationLandscape=false - -# These will be injected into docProps/app.xml -# if App.Write=true -docx4j.App.write=true -docx4j.Application=docx4j -docx4j.AppVersion=2.7 -# of the form XX.YYYY where X and Y represent numerical values - -# These will be injected into docProps/core.xml -docx4j.dc.write=true -docx4j.dc.creator.value=docx4j -docx4j.dc.lastModifiedBy.value=docx4j - -# -#docx4j.McPreprocessor=true - -# If you haven't configured log4j yourself -# docx4j will autoconfigure it. Set this to true to disable that -docx4j.Log4j.Configurator.disabled=false diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/log4j.properties b/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/log4j.properties deleted file mode 100644 index 4404dbcb16a95486f76c0cf00064d490efe8e1a8..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/log4j.properties +++ /dev/null @@ -1,4 +0,0 @@ -log4j.rootLogger=WARN, console -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.conversionPattern=%5p [%t] (%F:%L) - %m%n diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/log4j.xml b/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/log4j.xml deleted file mode 100644 index 0a59d3b28ceb1b1dcd894cd5ec63917eab80e1fa..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/src/resources/log4j.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.ttcn3.ui/.classpath b/plugins/org.etsi.mts.tdl.ttcn3.ui/.classpath index 1db08c6b4ce2fb50395b2f9c9a50c140a0bab199..c0015778137ba86ca96d5d047b0e5a28d33457a6 100644 --- a/plugins/org.etsi.mts.tdl.ttcn3.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.ttcn3.ui/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.ttcn3.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.ttcn3.ui/.settings/org.eclipse.jdt.core.prefs index 402051ba9fb8d5fed4ff1a609449b764896e9083..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.ttcn3.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.ttcn3.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.ttcn3.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.ttcn3.ui/META-INF/MANIFEST.MF index c3b3618e936bb08b19c0c502ef4d47cacfab3caa..3d5a6afc76cbcace419c6035bfb0a17ed94be5aa 100644 --- a/plugins/org.etsi.mts.tdl.ttcn3.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.ttcn3.ui/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Ui +Automatic-Module-Name: org.etsi.mts.tdl.ttcn3.ui +Bundle-Name: TDL to TTCN-3 Generation UI Bundle-SymbolicName: org.etsi.mts.tdl.ttcn3.ui;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.etsi.mts.tdl.ttcn3.ui.Activator @@ -10,12 +11,9 @@ Require-Bundle: org.eclipse.ui, org.eclipse.ui.editors;bundle-version="3.5.0", org.eclipse.ui.ide;bundle-version="3.5.0", org.eclipse.ui.workbench, - org.eclipse.emf.common, org.eclipse.emf.ecore, org.eclipse.xtext, - org.eclipse.xtext.ui, - org.etsi.mts.tdl.ttcn3, - de.ugoe.cs.swe.TTCN3, - de.ugoe.cs.swe.TTCN3.ui -Bundle-RequiredExecutionEnvironment: JavaSE-11 + org.etsi.mts.tdl.model, + org.etsi.mts.tdl.ttcn3 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Bundle-ActivationPolicy: lazy diff --git a/plugins/org.etsi.mts.tdl.ttcn3.ui/plugin.xml b/plugins/org.etsi.mts.tdl.ttcn3.ui/plugin.xml index afcdfec3804f610eac2fc96483162b4ec98673f4..f5e8bb0ec54a24863ba5e981401ab95cfd35b4da 100644 --- a/plugins/org.etsi.mts.tdl.ttcn3.ui/plugin.xml +++ b/plugins/org.etsi.mts.tdl.ttcn3.ui/plugin.xml @@ -9,27 +9,18 @@ id="org.etsi.mts.tdl.ttcn3.ui.commands.category"> + id="org.etsi.mts.tdl.ttcn3.ui.commands.translateTTCN3Command"> + commandId="org.etsi.mts.tdl.ttcn3.ui.commands.translateTTCN3Command" + class="org.etsi.mts.tdl.ttcn3.ui.handlers.RendererHandler"> - - - - + id="org.etsi.mts.tdl.ttcn3.ui.menus.translateTTCN3Command"> @@ -51,10 +42,10 @@ + tooltip="Generate TTCN-3 code from TDL model" + id="org.etsi.mts.tdl.ttcn3.ui.toolbars.translateTTCN3Command"> diff --git a/plugins/org.etsi.mts.tdl.ttcn3.ui/src/org/etsi/mts/tdl/ttcn3/ui/handlers/RendererHandler.java b/plugins/org.etsi.mts.tdl.ttcn3.ui/src/org/etsi/mts/tdl/ttcn3/ui/handlers/RendererHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..853111de543395860878668ac370a1b4c137895c --- /dev/null +++ b/plugins/org.etsi.mts.tdl.ttcn3.ui/src/org/etsi/mts/tdl/ttcn3/ui/handlers/RendererHandler.java @@ -0,0 +1,155 @@ +package org.etsi.mts.tdl.ttcn3.ui.handlers; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.resource.XtextResourceSet; +import org.etsi.mts.tdl.ttcn3.TTCN3Renderer; +import org.etsi.mts.tdl.Package; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * Our sample handler extends AbstractHandler, an IHandler base class. + * @see org.eclipse.core.commands.IHandler + * @see org.eclipse.core.commands.AbstractHandler + */ +public class RendererHandler extends AbstractHandler { + LinkedHashMap targetFormats = new LinkedHashMap<>(); + + public static String translationTarget = "TTCN-3 (Part 6)"; + + private IWorkbenchWindow window; + + /** + * The constructor. + */ + public RendererHandler() { + init(); + } + + private void init() { + //TODO: do not reload after first init + if (!targetFormats.isEmpty()) { +// return; + } + targetFormats.clear(); + targetFormats.put("TTCN-3 (Part 6)", "ttcn3"); +// loadTargetFormat("org.etsi.mts.tdl.tx", "TDL TX (Part 8, Braces)", "tdltx"); +// loadTargetFormat("org.etsi.mts.tdl.txi", "TDL TX (Part 8, Indentation)", "tdltxi"); +// loadTargetFormat("org.etsi.mts.tdl.TDLan2", "TDLan2 (Part 1, Annex B)", "tdlan2"); +// loadTargetFormat("org.etsi.mts.tdl.TPLan2", "TPLan2 (Part 4, Annex B)", "tplan2"); + } + + private void loadTargetFormat(String bundleName, String label, String extension) { + if (Platform.getBundle(bundleName) != null) { + targetFormats.put(label, extension); + } + } + + /** + * the command has been executed, so extract extract the needed information + * from the application context. + */ + public Object execute(ExecutionEvent event) throws ExecutionException { + init(); + ISelection selection = HandlerUtil.getCurrentSelection(event); + IEditorInput input = HandlerUtil.getActiveEditorInput(event); + IFile file = null; + if (input != null && input instanceof FileEditorInput) { + file = ((FileEditorInput) input).getFile(); + } else if (selection !=null && selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + Object firstElement = structuredSelection.getFirstElement(); + if (firstElement instanceof IFile) { + file = (IFile) firstElement; + } + } + + if (file !=null) { + URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); + Injector injector = Guice.createInjector(); + XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class); +// ResourceSet rs = new ResourceSetImpl(); + XtextResourceSet rs = resourceSet; + Resource r = rs.getResource(uri, true); + EcoreUtil.resolveAll(r); + + ElementListSelectionDialog dialog = new ElementListSelectionDialog(Display.getDefault().getActiveShell(), new LabelProvider()); + dialog.setTitle("Translation Configuration"); + dialog.setMessage("Translating "+file.getName() + +"\n\nSelect the target format"); + dialog.setElements(targetFormats.keySet().toArray()); + + dialog.setInitialElementSelections(Arrays.asList(new String[] {RendererHandler.translationTarget})); + + // user pressed cancel + if (dialog.open() != Window.OK) { + return false; + } else { + Object[] result = dialog.getResult(); + String selected = (String)result[0]; + RendererHandler.translationTarget = selected; + String extension = targetFormats.get(selected); + + TTCN3Renderer ttcn3 = new TTCN3Renderer(); + + List packages = EcoreUtil2.getAllContentsOfType(r, Package.class); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + for (Package p : packages) { + String output = ""; + output += ttcn3.render(p, " "); + IPath target = file.getFullPath().removeLastSegments(1).append(p.getName()).addFileExtension(extension); + IFile targetFile = root.getFile(target); + try { + if (!targetFile.exists()) { + targetFile.create(output.getBytes(), 0, null); + } else { + targetFile.setContents(output.getBytes(), true, true, null); + } + } catch (CoreException e) { + e.printStackTrace(); + } + + } + } + } + return null; + } + + public void init(IWorkbenchWindow window) { + this.window = window; + } + + @Override + public boolean isEnabled() { + return true; + } + +} diff --git a/plugins/org.etsi.mts.tdl.ttcn3.ui/src/org/etsi/mts/tdl/ttcn3/ui/handlers/TransformationHandler.java b/plugins/org.etsi.mts.tdl.ttcn3.ui/src/org/etsi/mts/tdl/ttcn3/ui/handlers/TransformationHandler.java deleted file mode 100644 index fca0dca1f6365fa5acce3de7acfa0a1667ab48d5..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.ttcn3.ui/src/org/etsi/mts/tdl/ttcn3/ui/handlers/TransformationHandler.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.etsi.mts.tdl.ttcn3.ui.handlers; - -import org.eclipse.core.commands.AbstractHandler; -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.handlers.HandlerUtil; -import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.xtext.resource.XtextResourceSet; -import org.eclipse.xtext.ui.resource.IResourceSetProvider; -import org.etsi.mts.tdl.ttcn3.Transform; - -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.Provider; - -/** - * Our sample handler extends AbstractHandler, an IHandler base class. - * @see org.eclipse.core.commands.IHandler - * @see org.eclipse.core.commands.AbstractHandler - */ -public class TransformationHandler extends AbstractHandler { - @Inject Injector injector; - @Inject Provider rsp; - @Inject Provider xrsp; - - - @Inject IResourceSetProvider resourceSetProvider; - - private IWorkbenchWindow window; - - /** - * The constructor. - */ - public TransformationHandler() { - } - - /** - * the command has been executed, so extract extract the needed information - * from the application context. - */ - public Object execute(ExecutionEvent event) throws ExecutionException { - ISelection selection = HandlerUtil.getCurrentSelection(event); - IEditorInput input = HandlerUtil.getActiveEditorInput(event); - IFile file = null; - if (input != null && input instanceof FileEditorInput) { - file = ((FileEditorInput) input).getFile(); - } else if (selection !=null && selection instanceof IStructuredSelection) { - IStructuredSelection structuredSelection = (IStructuredSelection) selection; - Object firstElement = structuredSelection.getFirstElement(); - if (firstElement instanceof IFile) { - file = (IFile) firstElement; - } - } - try { - if (file !=null) { - injector = Guice.createInjector(); - URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); - XtextResourceSet rs = injector.getInstance(XtextResourceSet.class); - Resource r = rs.getResource(uri, true); - EcoreUtil.resolveAll(r); //This is important otherwise weird problems occur if unresolved imported definitions are encountered - if (file.getName().endsWith(".tdl") - || file.getName().endsWith(".tdlan2") - || file.getName().endsWith(".tdltx") - || file.getName().endsWith(".tdltxi")) { - Transform transformer = new Transform(); - - URI interimURI = URI.createURI(uri.toString()+"-generated.ttcn3m"); - Resource ir = rs.createResource(interimURI); - transformer.transform(r, ir); - //This is important otherwise ghost references may occur - ir.unload(); - URI targetURI = URI.createURI(uri.toString()+"-generated.ttcn3"); - // URI targetURI = URI.createPlatformResourceURI(file.getFullPath().toString()+".ttcn3", true); - // Injector injector = Guice.createInjector(new de.ugoe.cs.swe.TTCN3RuntimeModule()); - // XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class); - // Resource tr = resourceSet.createResource(targetURI); - Resource tr = rs.createResource(targetURI); - transformer.transform(r, tr); - } else if (file.getName().endsWith(".ttcn3")) { - URI targetURI = URI.createURI(uri.toString()+".ttcn3m"); - Resource tr = rs.createResource(targetURI); - tr.getContents().addAll(EcoreUtil.copyAll(r.getContents())); - tr.save(null); - } else if (file.getName().endsWith(".ttcn3m")) { - URI targetURI = URI.createURI(uri.toString()+".ttcn3"); - Resource tr = rs.createResource(targetURI); - tr.getContents().addAll(EcoreUtil.copyAll(r.getContents())); - tr.save(null); - } - - } - } catch (Exception e) { - System.err.println(" Transformation: "+e.getMessage()); - //TODO: add dialog - } - return null; - } - public void init(IWorkbenchWindow window) { - this.window = window; - } - - @Override - public boolean isEnabled() { - return true; - } -} diff --git a/plugins/org.etsi.mts.tdl.ttcn3/.classpath b/plugins/org.etsi.mts.tdl.ttcn3/.classpath index 344e4ab0785c637094fd70159c6841c670b4248b..fb03465e87f180adf8c01ef92427fe495de1dbf8 100644 --- a/plugins/org.etsi.mts.tdl.ttcn3/.classpath +++ b/plugins/org.etsi.mts.tdl.ttcn3/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.ttcn3/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.ttcn3/.settings/org.eclipse.jdt.core.prefs index 4a7e0723d6efee0525a636a07706c95bbbe13f88..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.ttcn3/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.ttcn3/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.ttcn3/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.ttcn3/META-INF/MANIFEST.MF index 92785ff9416e55bc559536fea52d91f9ae4a394e..5021ffd6365ac173c0ac2ed0aa1b0f07ecbb0db8 100644 --- a/plugins/org.etsi.mts.tdl.ttcn3/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.ttcn3/META-INF/MANIFEST.MF @@ -1,19 +1,10 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: TDL to TTCN-3 Core +Bundle-Name: TDL to TTCN-3 Generation Core Bundle-SymbolicName: org.etsi.mts.tdl.ttcn3 Bundle-Version: 1.0.0.qualifier Automatic-Module-Name: org.etsi.mts.tdl.ttcn3 -Bundle-RequiredExecutionEnvironment: JavaSE-11 -Require-Bundle: org.eclipse.emf.common, - org.eclipse.core.runtime, - org.eclipse.emf.ecore, - org.eclipse.osgi, - org.etsi.mts.tdl.model, - de.ugoe.cs.swe.TTCN3;resolution:=optional, - org.eclipse.epsilon.common, - org.eclipse.epsilon.emc.emf, - org.eclipse.epsilon.eol.engine, - org.eclipse.epsilon.etl.engine, - org.etsi.mts.tdl.common +Bundle-RequiredExecutionEnvironment: JavaSE-21 +Require-Bundle: org.etsi.mts.tdl.model, + org.eclipse.xtext Export-Package: org.etsi.mts.tdl.ttcn3 diff --git a/plugins/org.etsi.mts.tdl.ttcn3/src/org/etsi/mts/tdl/ttcn3/TTCN3Renderer.java b/plugins/org.etsi.mts.tdl.ttcn3/src/org/etsi/mts/tdl/ttcn3/TTCN3Renderer.java new file mode 100644 index 0000000000000000000000000000000000000000..8e9a3dca4168e70cbe0348a3be902840f37923eb --- /dev/null +++ b/plugins/org.etsi.mts.tdl.ttcn3/src/org/etsi/mts/tdl/ttcn3/TTCN3Renderer.java @@ -0,0 +1,855 @@ +package org.etsi.mts.tdl.ttcn3; + +import org.etsi.mts.tdl.Package; +import org.etsi.mts.tdl.PackageableElement; +import org.etsi.mts.tdl.Parameter; +import org.etsi.mts.tdl.ParameterBinding; +import org.etsi.mts.tdl.PredefinedFunctionCall; +import org.etsi.mts.tdl.SimpleDataInstance; +import org.etsi.mts.tdl.SimpleDataType; +import org.etsi.mts.tdl.Stop; +import org.etsi.mts.tdl.StructuredDataInstance; +import org.etsi.mts.tdl.StructuredDataType; +import org.etsi.mts.tdl.TestConfiguration; +import org.etsi.mts.tdl.TestDescription; +import org.etsi.mts.tdl.TestObjective; +import org.etsi.mts.tdl.TimeOut; +import org.etsi.mts.tdl.TimerStart; +import org.etsi.mts.tdl.TimerStop; +import org.etsi.mts.tdl.UnboundedLoopBehaviour; +import org.etsi.mts.tdl.VariableUse; +import org.etsi.mts.tdl.VerdictAssignment; + +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.etsi.mts.tdl.Action; +import org.etsi.mts.tdl.ActionReference; +import org.etsi.mts.tdl.AlternativeBehaviour; +import org.etsi.mts.tdl.Annotation; +import org.etsi.mts.tdl.AnnotationType; +import org.etsi.mts.tdl.AnyValue; +import org.etsi.mts.tdl.AnyValueOrOmit; +import org.etsi.mts.tdl.Assertion; +import org.etsi.mts.tdl.Assignment; +import org.etsi.mts.tdl.AtomicBehaviour; +import org.etsi.mts.tdl.Behaviour; +import org.etsi.mts.tdl.Block; +import org.etsi.mts.tdl.BoundedLoopBehaviour; +import org.etsi.mts.tdl.Break; +import org.etsi.mts.tdl.CastDataUse; +import org.etsi.mts.tdl.CollectionDataInstance; +import org.etsi.mts.tdl.CollectionDataType; +import org.etsi.mts.tdl.ComponentInstance; +import org.etsi.mts.tdl.ComponentInstanceRole; +import org.etsi.mts.tdl.ComponentType; +import org.etsi.mts.tdl.CompoundBehaviour; +import org.etsi.mts.tdl.ConditionalBehaviour; +import org.etsi.mts.tdl.DataElementUse; +import org.etsi.mts.tdl.DataType; +import org.etsi.mts.tdl.DataUse; +import org.etsi.mts.tdl.Element; +import org.etsi.mts.tdl.EnumDataType; +import org.etsi.mts.tdl.Function; +import org.etsi.mts.tdl.GateType; +import org.etsi.mts.tdl.InlineAction; +import org.etsi.mts.tdl.LiteralValueUse; +import org.etsi.mts.tdl.Member; +import org.etsi.mts.tdl.Message; +import org.etsi.mts.tdl.NamedElement; +import org.etsi.mts.tdl.OmitValue; + +public class TTCN3Renderer { + private List binaryFunctions = List.of("+", "-", "*", "/", "mod", "or", "and", "xor", "!=", "<", ">", "<=", ">=", "=="); + private List keywords = List.of("message", "port", "value", "length", "type", "trigger", "self"); + private String indent = " "; + private String LF = "\n"; + + //TODO: resolve mappings? + String ttcnName(NamedElement e) { + String cleanName = e.getName(); + if (keywords.contains(cleanName)) { + cleanName+="_"; + } + if (cleanName.startsWith("_")) { + cleanName="N"+cleanName; + } + return cleanName; + } + + public String render(Package p, String indent) { + String output = ""; + output+=renderAnnotations(p, indent); + output += "module "+ttcnName(p)+" {"+LF; + for (var i : p.getImport()) { + //TODO: import individual elements + output+=indent+this.indent+"import from "+ttcnName(i.getImportedPackage())+" all;"+LF; + } + output+=indent+this.indent+"modulepar float mp_componentElapsedTimerMaxDuration;"+LF; + //TODO: outsource in a library? -> leads to duplications all over + output+=indent+this.indent+"type charstring SimpleDataType;"+LF; + output+=indent+this.indent+"type charstring String;"+LF; + output+=indent+this.indent+"type integer Integer;"+LF; + output+=indent+this.indent+"type boolean Boolean;"+LF; + output+=indent+this.indent+"altstep to_handle_deviations_from_TDL_description_AS () {"+LF + + indent+this.indent+this.indent+"[ ] any port.receive {"+LF + + indent+this.indent+this.indent+this.indent+"setverdict(fail);"+LF + + indent+this.indent+this.indent+"}"+LF + + indent+this.indent+this.indent+"[ ] any port.getcall {"+LF + + indent+this.indent+this.indent+this.indent+"setverdict(fail);"+LF + + indent+this.indent+this.indent+"}"+LF + + indent+this.indent+"}"+LF; + for (var e : p.getPackagedElement()) { + output+=render(e, indent+this.indent); + } + output +="}"+LF; + //TODO: split nested into files? -> handle upstream + //TODO: prefix nested? +// for (var n : p.getNestedPackage()) { +// output+=render(n, indent); +// } + return output; + } + + String render(PackageableElement e, String indent) { + return renderAnnotations(e, indent) + switch (e) { + //TODO: packages in separate files? or only top-level? + case StructuredDataType r -> render(r, indent); + case StructuredDataInstance r -> render(r, indent); + case EnumDataType r -> render(r, indent); + case SimpleDataType r -> render(r, indent); + case SimpleDataInstance r -> render(r, indent); + case CollectionDataType r -> render(r, indent); + case CollectionDataInstance r -> render(r, indent); + case Function r -> render(r, indent); + case Action r -> render(r, indent); + case TestDescription r -> render(r, indent); + case GateType r -> render(r, indent); + case ComponentType r -> render(r, indent); + case TestConfiguration r -> render(r, indent); + default -> renderUnsupported(e, indent); + }; + } + + String render(StructuredDataType e, String indent) { + String output = ""; + //TODO: handle union, etc? + output+=indent+"type record "+ttcnName(e)+" {"+LF; + //TODO: handle extensions? -> use union for super type with subtypes as fields? + output+=e.allMembers().stream() + .map(m -> indent+this.indent+ttcnName(m.getDataType())+" "+ttcnName(m)+optional(m)) + .collect(Collectors.joining(","+LF))+LF; + + output+=renderExtensions(e, indent); + output+=indent+"}"+LF; + return output; + } + + String renderExtensions(StructuredDataType e, String indent) { + String output = ""; + List extensions = EcoreUtil2.getAllContentsOfType(e.eResource(), StructuredDataType.class).stream() +// .map(t -> t.getExtension()) +// .flatMap(t -> t.stream()) +// .filter(t -> t.getExtending() == e) +// .map(t -> (StructuredDataType)t.getExtending()) + .filter(t -> t.getExtension().stream().anyMatch(x -> x.getExtending() == e)) + .toList(); + if (!extensions.isEmpty()) { + output+=indent+this.indent+"union {"+LF; + output+=extensions.stream().map(x -> renderExtension(x, indent+this.indent+this.indent)).collect(Collectors.joining(","+LF))+LF; + output+=indent+this.indent+"} extensions optional"+LF; + } + return output; + } + + private String renderExtension(StructuredDataType t, String indent) { + String output = ""; + output+=indent+"record {"+LF; + output+=t.allMembers().stream() + .map(m -> indent+this.indent+ttcnName(m.getDataType())+" "+ttcnName(m)+optional(m)) + .collect(Collectors.joining(","+LF))+LF; + output+=indent+"} "+ttcnName(t); + return output; + } + + String optional(Member m) { + return m.isIsOptional() ? " optional" : ""; + } + + String render(StructuredDataInstance e, String indent) { + String output = ""; + output+=indent+"template "+ttcnName(e.getDataType())+" "+ttcnName(e)+" := {"+LF; + //TODO: unassigned + output+=e.getMemberAssignment().stream() + .map(m -> indent+this.indent+ttcnName(m.getMember())+" := "+render(m.getMember(), m.getMemberSpec(), indent)) + .collect(Collectors.joining(",\n"))+LF; + output+=indent+"}"+LF; + return output; + } + + //TODO: handle true, false, pass, fail + String render(SimpleDataInstance e, String indent) { + String output = ""; + output+=indent+"template "+ttcnName(e.getDataType())+" "+ttcnName(e)+" := \""+ttcnName(e)+"\";"+LF; + return output; + } + + String render(SimpleDataType e, String indent) { + String output = ""; + output+=indent+"type SimpleDataType "+ttcnName(e)+";"+LF; + return output; + } + + String render(EnumDataType e, String indent) { + String output = ""; + output+=indent+"type enumerated "+ttcnName(e)+" {"+LF; + output+=e.getValue().stream() + .map(m -> indent+this.indent+ttcnName(m)) + .collect(Collectors.joining(",\n"))+LF; + output+=indent+"}"+LF; + return output; + } + + String render(CollectionDataType e, String indent) { + String output = ""; + output+=indent+"type record of "+ttcnName(e.getItemType())+" "+ttcnName(e)+";"+LF; + return output; + } + + //TODO: spec is erroneous + //TODO: some templating language might have made sense so it could be used directly in the spec.. + String render(CollectionDataInstance e, String indent) { + String output = ""; + output+=indent+"template "+ttcnName(e.getDataType())+" "+ttcnName(e)+" {"+LF; + //TODO: unassigned + output+=e.getItem().stream() + .map(m -> indent+this.indent+render(m, indent+this.indent)) + .collect(Collectors.joining(","+LF))+LF; + output+=indent+"}"+LF; + return output; + } + + String render(Function e, String indent) { + String output = ""; + String parameter = e.getFormalParameter().stream() + .map(m -> ttcnName(m.getDataType()) +" "+ttcnName(m)) + .collect(Collectors.joining(",")); + output+=indent+"function "+ttcnName(e)+" ("+parameter+") return "+ttcnName(e.getReturnType())+"{"+LF; + output+=indent+this.indent+"/* "+LF; + if (e.getBody()!=null) { + output+=indent+this.indent+e.getBody()+LF; + } + output+=indent+this.indent+"*/"+LF; + output+=indent+"}"+LF; + return output; + } + + String render(Action e, String indent) { + String output = ""; + String parameter = e.getFormalParameter().stream() + .map(m -> ttcnName(m.getDataType()) +" "+ttcnName(m)) + .collect(Collectors.joining(",")); + output+=indent+"function "+ttcnName(e)+" ("+parameter+") {"+LF; + output+=indent+this.indent+"/* "+LF; + output+=indent+this.indent+e.getBody()+LF; + output+=indent+this.indent+"*/"+LF; + output+=indent+"}"+LF; + return output; + } + + String render(DataUse e, String indent) { + return switch (e) { + case DataElementUse u -> render(u, indent); + case LiteralValueUse u -> render(u, indent); + case AnyValue u -> "?"; + case AnyValueOrOmit u -> "*"; + case OmitValue u -> "omit"; + case CastDataUse u -> render(u, indent); + case PredefinedFunctionCall u -> render(u, indent); + case VariableUse u -> render(u, indent); + default -> renderUnsupported(e, indent); + } + ; + } + + String render(DataElementUse e, String indent) { + String output = ""; + //TODO: arguments, reduction, other.. + //TODO: anonymous types + //TODO: with or without parameters, {} vs () + String arguments =e.getArgument().stream() + .map(m -> render(m.getDataUse(), "")) + .collect(Collectors.joining(", ")); + String assignedArguments =e.getArgument().stream() + .map(m -> ttcnName(m.getParameter())+" := "+render(m.getParameter(), m.getDataUse(), "")) + .collect(Collectors.joining(", ")); + String items =e.getItem().stream() + .map(m -> render(m, "")) + .collect(Collectors.joining(", ")); + + if (e.getDataElement()!=null) { + NamedElement dataElement = e.getDataElement(); + output+=switch (dataElement) { + case StructuredDataType d -> output+="{"+assignedArguments+"}"; + case StructuredDataInstance d -> output+=ttcnName(e.getDataElement()); + case Function d -> output+=ttcnName(e.getDataElement())+"("+arguments+")"; + case Parameter d -> output+=ttcnName(e.getDataElement()); + case SimpleDataInstance d -> output+=ttcnName(e.getDataElement()); + case CollectionDataType d -> output+="{"+items+"}"; + default -> "NOT_SUPPORTED_YET"; + }; + } else { + DataType dataType = e.resolveDataType(); + output+=switch (dataType) { + case StructuredDataType d -> output+="{"+assignedArguments+"}"; + case CollectionDataType d -> output+="{"+items+"}"; + //TODO: collections + default -> "NOT_SUPPORTED_YET"; + }; + + } + output+=renderReduction(e, indent); + return output; + } + + String render(Parameter p, DataUse e, String indent) { + String output = ""; + //TODO: check that it conforms? + //TODO: add to spec? + String direct = render(e, ""); + if (p.getDataType() instanceof StructuredDataType) { + if (e.resolveDataType() == p.getDataType()) { + output+=direct; + } else { + output+="{ extensions := { "+ttcnName(e.resolveDataType())+" := "+render(e, "")+"}}"; + } + } else { + output+=direct; + } + return output; + } + + String render(CastDataUse e, String indent) { + //TODO: add to spec? + String output = ""; + output+=render(e.getDataUse(), ""); + //skip superfluous casts + if (e.getDataType() != e.getDataUse().resolveDataType()) { + output+=".extensions."+ttcnName(e.getDataType()); + } + output+=renderReduction(e, indent); + return output; + } + + String renderReduction(DataUse e, String indent) { + String output = ""; + if (!e.getReduction().isEmpty()) { + output+="."+e.getReduction().stream().map(m -> ttcnName(m.getMember())).collect(Collectors.joining(".")); + } + return output; + } + + String render(LiteralValueUse e, String indent) { + String output = ""; + if (e.getValue()!=null) { + output+="\""+e.getValue()+"\""; + } else if (e.getIntValue() != null) { + output+=e.getIntValue(); + } else if (e.getBoolValue() != null) { + output+=e.getBoolValue(); + } + return output; + } + + String render(VariableUse e, String indent) { + String output = ""; + output += ttcnName(e.getVariable()); + return output; + } + + String render(PredefinedFunctionCall e, String indent) { + String output = ""; + String function = e.getFunction().getName(); + if (binaryFunctions.contains(function)) { + output+=""+render(e.getActualParameters().getFirst(), "")+" "+function+" "+render(e.getActualParameters().getLast(), ""); + } else if (function.equals("not")) { + output+="not("+render(e.getArgument().getFirst().getDataUse(), "")+")"; + } else if (function.equals("size")) { + output+="lengthof("+render(e.getArgument().getFirst().getDataUse(), "")+")"; + } + return output; + } + + String render(GateType e, String indent) { + String output = ""; + output+=indent+"type port "+ttcnName(e)+" message {"+LF; + output+=indent+this.indent+"inout "+e.getDataType().stream() + .map(m -> ttcnName(m)) + .collect(Collectors.joining(", "))+";"+LF; + output+=indent+"}"+LF; + return output; + } + + String render(ComponentType e, String indent) { + String output = ""; + output+=indent+"type component "+ttcnName(e)+" {"+LF; + String timers=e.getTimer().stream() + .map(m -> indent+this.indent+"timer "+ttcnName(m)) + .collect(Collectors.joining(";"+LF)); + String variables=e.getVariable().stream() + //TODO: value annotation? + .map(m -> indent+this.indent+"var template "+ttcnName(m.getDataType())+" "+ttcnName(m)) + .collect(Collectors.joining(";"+LF)); + String gates=e.getGateInstance().stream() + .map(m -> indent+this.indent+"port "+ttcnName(m.getType())+" "+ttcnName(m)) + .collect(Collectors.joining(";"+LF)); + output+=indent+this.indent+"timer T_elapsedTimeOfComponent := mp_componentElapsedTimerMaxDuration;"+LF; + if (!timers.isBlank()) output+=timers+";"+LF; + if (!variables.isBlank()) output+=variables+";"+LF; + output+=gates+";"+LF; + + output+=indent+"}"+LF; + return output; + } + + String render(TestConfiguration e, String indent) { + String output = ""; + output+=indent+"type component MTC_"+ttcnName(e)+" {"+LF; + + for (var c : e.getComponentInstance()) { + if (c.getRole() == ComponentInstanceRole.TESTER) { + output+=indent+this.indent+"var "+ttcnName(c.getType())+" vc_"+ttcnName(c)+";"+LF; + } + } + + output+=indent+"}"+LF; + + output+=indent+"type component System_"+ttcnName(e)+" {"+LF; + for (var c : e.getComponentInstance()) { + //TODO: handle duplicates / special cases? + if (c.getRole() == ComponentInstanceRole.SUT) { + String gates=c.getType().getGateInstance().stream() + .map(m -> indent+this.indent+"port "+ttcnName(m.getType())+" "+ttcnName(m)) + .collect(Collectors.joining(";"+LF)); + output+=gates+";"+LF; + } + } + + output+=indent+"}"+LF; + + output+=indent+"function "+getTestConfigurationFunctionName(e)+"() runs on MTC_"+ttcnName(e)+" {"+LF; + for (var c : e.getComponentInstance()) { + if (c.getRole() == ComponentInstanceRole.TESTER) { + output+=indent+this.indent+"vc_"+ttcnName(c)+" := "+ttcnName(c.getType())+".create"+";"+LF; + //TODO: map and connect ports + } + } + for (var c : e.getConnection()) { + //TODO: multipoint + var c1 = c.getEndPoint().getFirst(); + var c2 = c.getEndPoint().getLast(); + String c1name = "vc_"+ttcnName(c1.getComponent()); + String c2name = "vc_"+ttcnName(c2.getComponent()); + String operation = "connect"; + if (c1.getComponent().getRole() == ComponentInstanceRole.SUT || c2.getComponent().getRole() == ComponentInstanceRole.SUT) { + if (c1.getComponent().getRole() == ComponentInstanceRole.SUT) { + c1name = "system"; + } + if (c2.getComponent().getRole() == ComponentInstanceRole.SUT) { + c2name = "system"; + } + operation = "map"; + } + output+=indent+this.indent+operation+"("+c1name+":"+ttcnName(c1.getGate())+", "+c2name+":"+ttcnName(c2.getGate())+");"+LF; + } + + output+=indent+"}"+LF; + + return output; + } + + String render(TestDescription e, String indent) { + if (!e.isIsLocallyOrdered()) { + return ""; + } + String parameter = e.getFormalParameter().stream() + .map(m -> ttcnName(m.getDataType()) +" "+ttcnName(m)) + .collect(Collectors.joining(",")); + String parameterNames = e.getFormalParameter().stream() + .map(m -> ttcnName(m)) + .collect(Collectors.joining(",")); + String output = indent+"testcase "+ttcnName(e)+"("+parameter+") runs on MTC_"+ttcnName(e.getTestConfiguration())+" system System_"+ttcnName(e.getTestConfiguration())+" {"+LF; + for (var o : e.getTestObjective()) { + output+=render(o, indent+this.indent); + } + output+=indent+this.indent+getTestConfigurationFunctionName(e.getTestConfiguration())+"();"+LF; + for (var c : e.getTestConfiguration().getComponentInstance()) { + if (c.getRole() == ComponentInstanceRole.TESTER) { + //TODO: update specification, add TD name + output+=indent+this.indent+"vc_"+ttcnName(c)+".start("+getStartFunctionName(e, c)+"("+parameterNames+"));"+LF; + } + } + output+=indent+this.indent+"all component.done"+LF; + output+=indent+"}"+LF; + + //TODO: note error in specification + for (var c : e.getTestConfiguration().getComponentInstance()) { + if (c.getRole() == ComponentInstanceRole.TESTER) { + output+=indent+"function "+getStartFunctionName(e, c)+"("+parameter+") runs on "+ttcnName(c.getType())+" {"+LF; + output+=indent+this.indent+"activate (to_handle_deviations_from_TDL_description_AS ());"+LF; + output+=indent+this.indent+"T_elapsedTimeOfComponent.start;"+LF; + output+=indent+this.indent+getBehaviourFunctionName(e, c)+"("+parameterNames+")"+LF; + output+=indent+"}"+LF; + } + } + + for (var c : e.getTestConfiguration().getComponentInstance()) { + if (c.getRole() == ComponentInstanceRole.TESTER) { + output+=indent+"function "+getBehaviourFunctionName(e, c)+"("+parameter+") runs on "+ttcnName(c.getType())+" {"+LF; + output+=indent+this.indent+"//TODO: behaviours, etc."+LF; + output+=render(e.getBehaviourDescription().getBehaviour(), indent+this.indent, c); + output+=indent+"}"+LF; + } + } + + return output; + } + + private String getBehaviourFunctionName(TestDescription e, ComponentInstance c) { + return "f_behaviourOf_"+ttcnName(c)+"_In_"+ttcnName(e); + } + + String getStartFunctionName(TestDescription e, ComponentInstance c) { + return "f_startOf_"+ttcnName(c)+"_In_"+ttcnName(e); + } + + String getTestConfigurationFunctionName(TestConfiguration e) { + return "f_setupTestConfiguration_"+ttcnName(e); + } + + String render(TestObjective e, String indent) { + String output = ""; + output+=indent+"/*"+LF; + output+=indent+this.indent+"Test Objective "+ttcnName(e)+LF; + output+=indent+this.indent+"Description: "+e.getDescription()+LF; + String uri = e.getObjectiveURI().stream().collect(Collectors.joining(",")); + output+=indent+this.indent+"Objective URI: "+uri+LF; + output+=indent+"*/"+LF; + return output; + } + + String render(Behaviour e, String indent, ComponentInstance c) { + String output = ""; + //TODO: this is probably useless.. -> in globally ordered tests.. + if (e.getParticipatingComponents().contains(c)) { + output+=renderAnnotations(e, indent); + output+=switch (e) { + case CompoundBehaviour u -> render(u, indent, c); + case BoundedLoopBehaviour u -> render(u, indent, c); + case UnboundedLoopBehaviour u -> render(u, indent, c); + case AlternativeBehaviour u -> render(u, indent, c); + case ConditionalBehaviour u -> render(u, indent, c); + case AtomicBehaviour u -> render(u, indent, c); + default -> renderUnsupported(e, indent); + }; + output+=renderObjectives(e, indent); + } + return output; + } + + String render(CompoundBehaviour e, String indent, ComponentInstance c) { + String output = ""; + String guard = ""; + //TODO: multiple guards on the same component -> check specification and update + if (!e.getBlock().getGuard().isEmpty()) { + String block = ""; + if (e.getBlock().getGuard().stream().anyMatch(g -> g.getComponentInstance() == c)) { + block = render(e.getBlock(), indent+this.indent, c); + } + for (var g : e.getBlock().getGuard()) { + if (g.getComponentInstance() == c) { + guard+="if ("+render(g.getExpression(), "")+") "; + output+=indent+guard+"{"+LF; + output+=block; + output+=indent+"}"+LF; + break;//TODO: Handle multiple? + } + } + } else { + output+=render(e.getBlock(), indent+this.indent, c); + } + return output; + } + + String render(Block e, String indent, ComponentInstance c) { + String output = ""; + for (var b : e.getBehaviour()) { + if (b.getParticipatingComponents().contains(c)) { + output+=render(b, indent, c); + } + } + return output; + } + + String renderSkipFirst(Block e, String indent, ComponentInstance c) { + String output = ""; + boolean first = true; + for (var b : e.getBehaviour()) { + if (!first && b.getParticipatingComponents().contains(c)) { + output+=render(b, indent, c); + } + first = false; + } + return output; + } + + String render(BoundedLoopBehaviour e, String indent, ComponentInstance c) { + String output = ""; + for (var g : e.getNumIteration()) { + if (g.getComponentInstance() == c) { + output+=indent+"for (var integer cv := 0; cv < "+render(g.getExpression(), "")+"; cv := cv+1) {"+LF; + output+=render(e.getBlock(), indent+this.indent, c); + output+=indent+"}"+LF; + } + } + return output; + } + + String render(UnboundedLoopBehaviour e, String indent, ComponentInstance c) { + String output = ""; + //TODO: no guard? + if (!e.getBlock().getGuard().isEmpty()) { + for (var g : e.getBlock().getGuard()) { + if (g.getComponentInstance() == c) { + output+=indent+"while ("+render(g.getExpression(), "")+") {"+LF; + output+=render(e.getBlock(), indent+this.indent, c); + output+=indent+"}"+LF; + } + } + } + return output; + } + + String render(AlternativeBehaviour e, String indent, ComponentInstance c) { + String output = ""; + output+=indent+"alt {"+LF; + for (var b : e.getBlock()) { + String guard = ""; + //TODO: how does it work for alt statements and non-participating components? -> update spec? + // currently filter at the behaviour super class - skip behaviours that do not involve c + if (!b.getGuard().isEmpty()) { + for (var g : b.getGuard()) { + if (g.getComponentInstance() == c) { + guard+= render(g.getExpression(), ""); + } + } + } + //TODO: modifies model -> figure out more elegant solution - clone? + String first = render(b.getBehaviour().getFirst(), "", c); + if (!first.isBlank()) { + output+=indent+this.indent+"["+guard+"] "+first.substring(0, first.length()-2)+" {"+LF; + output+=renderSkipFirst(b, indent+this.indent+this.indent, c); + output+=indent+this.indent+"}"+LF; + } + } + output+=indent+"}"+LF; + return output; + } + + String render(ConditionalBehaviour e, String indent, ComponentInstance c) { + String output = ""; + boolean first = true; + for (var b : e.getBlock()) { + String guard = ""; + //TODO: how does it work for alt statements and non-participating components? -> update spec? + // currently filter at the behaviour super class - skip behaviours that do not involve c + if (!b.getGuard().isEmpty()) { + for (var g : b.getGuard()) { + if (g.getComponentInstance() == c) { + guard+= render(g.getExpression(), ""); + if (first) { + output+=indent+"if ("+guard+") {"+LF; + } else { + output+=indent+"} else if ("+guard+") {"+LF; + } + } + } + } else { + output+=indent+"} else {"+LF; + } + output+=render(b, indent+this.indent+this.indent, c); + output+=indent+"}"+LF; + first = false; + } + return output; + } + + String render(AtomicBehaviour e, String indent, ComponentInstance c) { + return switch (e) { + case Message u -> render(u, indent, c); + case TimerStart u -> render(u, indent, c); + case TimerStop u -> render(u, indent, c); + case TimeOut u -> render(u, indent, c); + case Break u -> indent+"break;"+LF; //TODO: outside of combined / bounded / unbounded / alternative? + case Stop u -> indent+"mtc.stop"+LF; + case VerdictAssignment u -> indent+"setverdict("+render(u.getVerdict(), "")+")"+LF; + case Assertion u -> render(u, indent, c); + case Assignment u -> render(u, indent); + case ActionReference u -> render(u, indent, c); + case InlineAction u -> render(u, indent, c); + default -> renderUnsupported(e, indent); + }; + } + + String render(Message e, String indent, ComponentInstance c) { + //TODO: special cases, assignments + String output = ""; +// output+=indent+"//"+ttcnName(c)+" : "+NodeModelUtils.findActualNodeFor(e).getText().trim()+ " -> " +// +(e.getSourceGate().getComponent() == c || e.getTarget().getFirst().getTargetGate().getComponent() == c) +// +" :: " +// +e.getParticipatingComponents().contains(c) +// +LF; + //extra guard for globally ordered descriptions.. should actually not be needed.. + if (e.getSourceGate().getComponent() == c || e.getTarget().getFirst().getTargetGate().getComponent() == c) { + String operation = "receive"; + String port = ttcnName(e.getTarget().getFirst().getTargetGate().getGate()); + if (e.getSourceGate().getComponent() == c) { + port = ttcnName(e.getSourceGate().getGate()); + operation = "send"; + } + String argument = render(e.getArgument(), ""); + output+=indent+port+"."+operation+"("+argument+");"+LF; + } + return output; + } + + String render(TimerStart e, String indent, ComponentInstance c) { + String output = ""; + output+=indent+ttcnName(e.getTimer())+".start("+render(e.getPeriod(), "")+");"+LF; + return output; + } + + String render(TimerStop e, String indent, ComponentInstance c) { + String output = ""; + output+=indent+ttcnName(e.getTimer())+".stop;"+LF; + return output; + } + + String render(TimeOut e, String indent, ComponentInstance c) { + String output = ""; + output+=indent+ttcnName(e.getTimer())+".timeout;"+LF; + return output; + } + + String render(Assertion e, String indent, ComponentInstance c) { + String output = ""; + if (e.getComponentInstance() == c) { + String guard = render(e.getCondition(), ""); + output+=indent+"if ("+guard+") {"+LF; + output+=indent+"} else {"+LF; + if (e.getOtherwise()!=null) { + output+=indent+this.indent+"setverdict("+render(e.getOtherwise(), "")+")"+LF; + } else { + output+=indent+this.indent+"setverdict(fail)"+LF; + } + output+=indent+"}"+LF; + } + return output; + } + + String render(ActionReference e, String indent, ComponentInstance c) { + String output = ""; + String arguments =e.getArgument().stream() + .map(m -> render(m.getDataUse(), indent+this.indent)) + .collect(Collectors.joining(", ")); + output+=indent+ttcnName(e.getAction())+"("+arguments+")"+LF; + return output; + } + + String render(Assignment e, String indent) { + String output = ""; + //TODO: filter for component instance? + output+=indent+ttcnName(e.getVariable().getVariable())+" := "+render(e.getExpression(), "")+";"+LF; + return output; + } + + String render(InlineAction e, String indent, ComponentInstance c) { + String output = ""; + //TODO: code annotation support + output+=indent+"/*"+LF; + output+=indent+"INLINE ACTION "+LF; + output+=indent+e.getBody()+LF; + output+=indent+"*/"+LF; + return output; + } + + String render(AnnotationType e, String indent) { + String output = ""; + output+=indent+"/*"+LF; + output+=indent+"ANNOTATION TYPE"+ttcnName(e); + if (e.getExtension() != null) { + output+=" EXTENDS "+ttcnName(e.getExtension().getExtending()); + } + output+=LF; + output+=indent+"*/"+LF; + return output; + } + + String render(Annotation e, String indent) { + String output = ""; + //TODO: make LFs optional? + boolean compact = true; + if (compact) { + output+=indent+"/* ANNOTATION "+ttcnName(e.getKey()); + if (e.getValue()!=null) { + output+=" : "+e.getValue(); + } + output+=" */"+LF; + } else { + output+=indent+"/*"+LF; + output+=indent+"ANNOTATION "+ttcnName(e.getKey())+LF; + if (e.getValue()!=null) { + output+=indent+e.getValue()+LF; + } + output+=indent+"*/"+LF; + } + return output; + } + + String renderAnnotations(Element e, String indent) { + String output = ""; + for (var a : e.getAnnotation()) { + output+=render(a, indent); + } + return output; + } + + String renderObjectives(Behaviour e, String indent) { + String output = ""; + if (!e.getTestObjective().isEmpty()) { + String objectives = e.getTestObjective().stream().map(o -> ttcnName(o)).collect(Collectors.joining(", ")); + output+=indent+"/*"+LF; + output+=indent+"Test Objective Satisfied: "+objectives+LF; + output+=indent+"*/"+LF; + } + return output; + } + + + String renderUnsupported(Element e, String indent) { + String output = ""; + output+=indent+"//"+e.eClass().getName()+" Not supported yet!"+LF; + return output; + } + + public String getIndent() { + return indent; + } + + public void setIndent(String indent) { + this.indent = indent; + } + +} diff --git a/plugins/org.etsi.mts.tdl.ttcn3/src/org/etsi/mts/tdl/ttcn3/Transform.java b/plugins/org.etsi.mts.tdl.ttcn3/src/org/etsi/mts/tdl/ttcn3/Transform.java deleted file mode 100644 index 18b037caacd72540087d3d480cbbae4cc1435329..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.ttcn3/src/org/etsi/mts/tdl/ttcn3/Transform.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.etsi.mts.tdl.ttcn3; - -import java.net.URI; -import java.net.URL; - -import org.eclipse.core.runtime.Platform; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.epsilon.common.parse.problem.ParseProblem; -import org.eclipse.epsilon.emc.emf.EmfModel; -import org.eclipse.epsilon.emc.emf.InMemoryEmfModel; -import org.eclipse.epsilon.eol.exceptions.EolRuntimeException; -import org.eclipse.epsilon.eol.models.IModel; -import org.eclipse.epsilon.etl.EtlModule; -import org.etsi.mts.tdl.tdlPackage; -import org.etsi.mts.tdl.resources.ResourceHandler; -import org.osgi.framework.Bundle; - -import de.ugoe.cs.swe.tTCN3.TTCN3Package; - -public class Transform { - public void transform(Resource r, Resource tr) { - try { - //load transformation scripts - String source = "epsilon/ttcn3/ttcn3mapping.etl"; - URI uri = ResourceHandler.getSourceUri(this.getClass(), "org.etsi.mts.tdl.ttcn3", source); - - EtlModule module = new EtlModule(); - module.parse(uri); - - //TODO: integrate error reporting - if (module.getParseProblems().size() > 0) { - System.err.println("Parse errors occured..."); - for (ParseProblem problem : module.getParseProblems()) { - System.err.println(" ETL: "+problem.toString()); - } - } - - //load models - IModel tdlModel = getTDLModel(r, true, false); - IModel ttcnModel = getTTCNModel(tr, false, true); - tdlModel.load(); - ttcnModel.load(); - module.getContext().getModelRepository().addModel(tdlModel); - module.getContext().getModelRepository().addModel(ttcnModel); - - //execute - module.execute(); - - tdlModel.dispose(); -// ttcnModel.store(); - ttcnModel.dispose(); - //TODO: check if still necessary - //module.reset(); - - } catch (EolRuntimeException e) { - System.err.println(" EOL: "+e.getAst().getModule().getSourceUri().getPath()+" : "+e.getLine() +" : "+e.getMessage()+""); - } catch (Exception e) { - System.err.println(" Transformation: "+e.getMessage()); - //e.printStackTrace(); - } - - } - - //TODO: extract to shared library - public IModel getTDLModel(Resource resource, boolean read, boolean write) throws Exception { - EmfModel model; - model = new InMemoryEmfModel("TDL", resource, tdlPackage.eINSTANCE); - model.setStoredOnDisposal(write); - model.setReadOnLoad(read); - model.setCachingEnabled(true); - return model; - } - - public IModel getTTCNModel(Resource resource, boolean read, boolean write) throws Exception { - EmfModel model; - model = new InMemoryEmfModel("TTCN", resource, TTCN3Package.eINSTANCE); - model.setStoredOnDisposal(write); - model.setReadOnLoad(read); - model.setCachingEnabled(true); - return model; - } - - -} diff --git a/plugins/org.etsi.mts.tdl.tx.ide/.classpath b/plugins/org.etsi.mts.tdl.tx.ide/.classpath index 376d2e95d674426da468104d8af6541f0c43b7a4..2f9d36fdfabd47830d7368f2c184d13bf7d7530d 100644 --- a/plugins/org.etsi.mts.tdl.tx.ide/.classpath +++ b/plugins/org.etsi.mts.tdl.tx.ide/.classpath @@ -1,6 +1,6 @@ - + diff --git a/plugins/org.etsi.mts.tdl.tx.ide/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.tx.ide/.settings/org.eclipse.jdt.core.prefs index 4066686a7037980436d75a26d2be734e098c76e5..3a79233b1335743cc32ed3638c1a2d0c1f52d303 100644 --- a/plugins/org.etsi.mts.tdl.tx.ide/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.tx.ide/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.tx.ide/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.tx.ide/META-INF/MANIFEST.MF index 1188a6213246f16bd2079cb4ea05f536428a9281..a54c8a184c2d5e15740ad8eb842c8005d34f039a 100644 --- a/plugins/org.etsi.mts.tdl.tx.ide/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.tx.ide/META-INF/MANIFEST.MF @@ -11,6 +11,6 @@ Require-Bundle: org.etsi.mts.tdl.tx, org.eclipse.xtext.ide, org.eclipse.xtext.xbase.ide, org.antlr.runtime;bundle-version="[3.2.0,3.2.1)" -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.ide.contentassist.antlr.internal, org.etsi.mts.tdl.ide.contentassist.antlr diff --git a/plugins/org.etsi.mts.tdl.tx.tests/.classpath b/plugins/org.etsi.mts.tdl.tx.tests/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..7931ec26b9119b03ff83dea3426230287acbc979 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/.classpath @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.etsi.mts.tdl.tools.to.docx/.project b/plugins/org.etsi.mts.tdl.tx.tests/.project similarity index 69% rename from plugins/org.etsi.mts.tdl.tools.to.docx/.project rename to plugins/org.etsi.mts.tdl.tx.tests/.project index 7c07cfdc41d6642b40e407825dcc234b6b464b5a..fbc482ffaeab4b94f10199cab833975da798c2cc 100644 --- a/plugins/org.etsi.mts.tdl.tools.to.docx/.project +++ b/plugins/org.etsi.mts.tdl.tx.tests/.project @@ -1,10 +1,15 @@ - org.etsi.mts.tdl.tools.to.docx + org.etsi.mts.tdl.tx.tests + + org.eclipse.xtext.ui.shared.xtextBuilder + + + org.eclipse.jdt.core.javabuilder @@ -28,18 +33,8 @@ org.eclipse.m2e.core.maven2Nature + org.eclipse.xtext.ui.shared.xtextNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature - - - 1681464246856 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - diff --git a/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.core.resources.prefs b/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000000000000000000000000000000000..99f26c0203a7844de00dbfc56e6a35d8ed3c022c --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..23fa13b170502d5a7f7a0549188dbc454a7cf0c8 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.m2e.core.prefs b/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.xtend.core.Xtend.prefs b/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.xtend.core.Xtend.prefs new file mode 100644 index 0000000000000000000000000000000000000000..9682a4c0a1113598fb0c6a4f406952addd84a30f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/.settings/org.eclipse.xtend.core.Xtend.prefs @@ -0,0 +1,7 @@ +//outlet.DEFAULT_OUTPUT.sourceFolder.src/main/java.directory=xtend-gen +//outlet.DEFAULT_OUTPUT.sourceFolder.src/test/java.directory=src/test/generated-sources/xtend +BuilderConfiguration.is_project_specific=true +eclipse.preferences.version=1 +outlet.DEFAULT_OUTPUT.hideLocalSyntheticVariables=true +outlet.DEFAULT_OUTPUT.installDslAsPrimarySource=false +outlet.DEFAULT_OUTPUT.userOutputPerSourceFolder=true diff --git a/plugins/org.etsi.mts.tdl.tx.tests/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.tx.tests/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..195c480a7428f7c11bb00b0c59a66deb1297cbc0 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/META-INF/MANIFEST.MF @@ -0,0 +1,25 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.etsi.mts.tdl.tx.tests +Bundle-Vendor: ETSI +Bundle-Version: 1.0.0.qualifier +Bundle-SymbolicName: org.etsi.mts.tdl.tx.tests;singleton:=true +Bundle-ActivationPolicy: lazy +Require-Bundle: org.etsi.mts.tdl.tx, + org.etsi.mts.tdl.model, + org.eclipse.xtext.testing, + org.eclipse.xtext.xbase.testing, + org.eclipse.xtext.xbase.lib, + org.eclipse.xtend.lib, + junit-jupiter-api, + junit-jupiter-engine, + junit-platform-launcher, + junit-platform-engine, + org.eclipse.equinox.app, + org.junit, + org.hamcrest.core, + org.eclipse.ocl.xtext.completeocl, + org.etsi.mts.tdl.common +Bundle-RequiredExecutionEnvironment: JavaSE-21 +Bundle-ClassPath: . +Export-Package: org.etsi.mts.tdl.tx.tests;x-internal=true diff --git a/plugins/org.etsi.mts.tdl.tx.tests/README.md b/plugins/org.etsi.mts.tdl.tx.tests/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8a36e801218c22432bee67ca6537fcad7cd624f8 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/README.md @@ -0,0 +1,57 @@ +# TDLtx Parsing Tests + +This plugin contains the test suite for the `TDLtx` Xtext grammar. It is designed to be highly scalable through dynamic test discovery. + +## Project Structure + +- `src/org.etsi.mts.tdl.tx.tests/TDLtxParsingTest.java`: The main test suite using JUnit 5 `@TestFactory`. +- `src/org.etsi.mts.tdl.tx.tests/TDLtxInjectorProvider.java`: Handles Guice injection and manual EMF `EPackage` registration for standalone execution. +- `src/models/`: **The primary location for test data.** Every `.tdltx` file in this folder is automatically picked up as a test case. + +## How to Add New Tests + +Adding a new parsing test case is a zero-code process: + +1. Navigate to `src/models/`. +2. Create a new file with the `.tdltx` extension (e.g., `my_new_feature.tdltx`). +3. Write your TDL model content inside the file. +4. Run the tests. + - On the first run, the suite will automatically create a `my_new_feature.expected` file containing the **Structural Snapshot** of the parsed model. + - **Manually verify** this `.expected` file to ensure the parser interpreted your TDL as intended (correct nesting, types, etc.). + - Subsequent runs will compare the parsed model against this baseline. + +## Verification Tiers + +The test suite performs three levels of verification for every model: + +1. **Syntactic:** Ensures the parser doesn't encounter any grammar errors. +2. **Semantic:** Uses `ValidationTestHelper` to ensure all cross-references (Types, Components, etc.) are resolved and TDL metamodel constraints are satisfied. +3. **Structural (Snapshot):** Dumps the resulting EObject tree (Types and Names) and compares it against a `.expected` file. This prevents **Syntax Ambiguity** where a model might parse without errors but result in the wrong internal structure. + +## How to Run Tests + +### In Eclipse IDE +1. Right-click on the `org.etsi.mts.tdl.tx.tests` project. +2. Select **Run As > JUnit Test**. +3. The JUnit view will show the dynamic list of files being parsed. + +### Headless / CLI +The tests can be run using the provided `build.xml` via the Eclipse `antRunner` application. + +**Command:** + +```bash +java -jar /plugins/org.eclipse.equinox.launcher_.jar \ + -nosplash \ + -application org.eclipse.ant.core.antRunner \ + -buildfile build.xml \ + -consoleLog +``` + +## Technical Details + +### Dynamic Discovery +The suite uses JUnit 5's `DynamicTest` feature. The `dynamicTestsFromFiles()` method scans the `src/models` directory at runtime. It employs multiple path-resolution strategies (ClassLoader, relative lookup, and environment fallbacks) to ensure it can find the models regardless of the execution environment. + +### Standalone Bootstrapping +Because TDL models rely on multiple EMF metamodels (Foundation, Structured Objectives, etc.), the `TDLtxInjectorProvider` and the static initializer in `TDLtxParsingTest` manually register these packages in the global `EPackage.Registry`. This bypasses the need for a full Eclipse extension registry during testing. diff --git a/plugins/org.etsi.mts.tdl.tx.tests/build.properties b/plugins/org.etsi.mts.tdl.tx.tests/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..4eb72aefdbe52f6b4f4d39dcd55c87a766436a8f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +bin.includes = META-INF/,\ + . + diff --git a/plugins/org.etsi.mts.tdl.tx.tests/build.xml b/plugins/org.etsi.mts.tdl.tx.tests/build.xml new file mode 100644 index 0000000000000000000000000000000000000000..80ea3b671806e84bbcec2e1066a8b842a52fb3ce --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/build.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/org.etsi.mts.tdl.tx.tests/pom.xml b/plugins/org.etsi.mts.tdl.tx.tests/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..6224a90dcbda9447f319750b2a69f7988ed3c739 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + + org.etsi.mts.tdl + org.etsi.mts.tdl.parent + 1.0.0-SNAPSHOT + ../../org.etsi.mts.tdl.parent + + org.etsi.mts.tdl.tx.tests + eclipse-test-plugin + + TDLtx Tests + + + + + org.eclipse.xtend + xtend-maven-plugin + + + org.eclipse.tycho + tycho-surefire-plugin + + false + false + false + + + + + + diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/loadModel.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/loadModel.expected new file mode 100644 index 0000000000000000000000000000000000000000..f4dda4ca387ec2c67f4451bbdd32b5323481304a --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/loadModel.expected @@ -0,0 +1,2 @@ +Package: testP + SimpleDataType: Dummy diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/loadModel.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/loadModel.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..393342b2538481c43f02acdbf39a41afd0620e2c --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/loadModel.tdltx @@ -0,0 +1,3 @@ +Package testP { + Type Dummy +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedBehaviour.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedBehaviour.expected new file mode 100644 index 0000000000000000000000000000000000000000..9e16fd30896754fffeca0eb7b951a85733c4f5c7 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedBehaviour.expected @@ -0,0 +1,22 @@ +Package: testP + Action: MyAction + GateType: mGate + SimpleDataType: MyType + ComponentType: MyCompType + GateInstance: g + TestConfiguration: MyConfig + ComponentInstance: c1Instance + ComponentInstance: c2Instance + Connection + GateReference + GateReference + TestDescription: MyTest + BehaviourDescription + CompoundBehaviour + Block + ActionReference + ConditionalBehaviour + Block + Stop + Block + Stop diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedBehaviour.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedBehaviour.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..2f760763314893aa8c63387ea551d86f06dcd401 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedBehaviour.tdltx @@ -0,0 +1,25 @@ +Package testP { + Action MyAction + + Message Gate mGate accepts MyType + Type MyType + + Component MyCompType { + gate mGate g + } + + Configuration MyConfig { + MyCompType c1Instance as SUT, + MyCompType c2Instance as Tester, + connect c1Instance::g to c2Instance::g + } + + Test Description MyTest uses MyConfig { + perform MyAction + if { + terminate + } else { + terminate + } + } +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedDataUse.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedDataUse.expected new file mode 100644 index 0000000000000000000000000000000000000000..2a4b5e7149202877751af3bb4e8f01c11b05c91b --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedDataUse.expected @@ -0,0 +1,68 @@ +Package: AdvancedDataUse + SimpleDataType: Integer + SimpleDataType: String + StructuredDataType: Address + Member: street + Member: zip + StructuredDataType: User + Member: name + Member: addr + CollectionDataType: Group + StructuredDataInstance: user1 + MemberAssignment + LiteralValueUse + MemberAssignment + DataElementUse + ParameterBinding + LiteralValueUse + ParameterBinding + LiteralValueUse + CollectionDataInstance: group1 + DataElementUse + DataElementUse + ParameterBinding + LiteralValueUse + ParameterBinding + DataElementUse + ParameterBinding + LiteralValueUse + ParameterBinding + LiteralValueUse + ComponentType: MyCompType + GateInstance: g + GateType: mGate + TestConfiguration: base + ComponentInstance: sutInstance + ComponentInstance: testerInstance + Connection + GateReference + GateReference + TestDescription: dataTest + BehaviourDescription + CompoundBehaviour + Block + Message + Target + DataElementUse + MemberReference + MemberReference + Message + Target + DataElementUse + MemberReference + LiteralValueUse + MemberReference + Message + Target + DataElementUse + ParameterBinding + LiteralValueUse + ParameterBinding + DataElementUse + MemberReference + Message + Target + DataElementUse + MemberReference + DataElementUse + SimpleDataInstance: index1 diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedDataUse.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedDataUse.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..a8796f7387fec6b00889391d7701c9591fa92eca --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testAdvancedDataUse.tdltx @@ -0,0 +1,55 @@ +Package AdvancedDataUse { + Type Integer + Type String + + Structure Address ( + String street, + Integer zip + ) + + Structure User ( + String name, + Address addr + ) + + Collection Group of User + + // Data Instances + User user1 ( name = "Alice", addr = Address ( street = "Main St", zip = 12345 ) ) + + Group group1 [ + user1, + User ( name = "Bob", addr = Address ( street = "Second St", zip = 54321 ) ) + ] + + Component MyCompType { + gate mGate g + } + + Message Gate mGate accepts User, Group, Integer, String + + Configuration base { + MyCompType sutInstance as SUT, + MyCompType testerInstance as Tester, + connect sutInstance::g to testerInstance::g + } + + Test Description dataTest uses base { + // Reduction: accessing member + testerInstance::g sends user1.addr.zip to sutInstance::g + + // Reduction: accessing collection element and member + testerInstance::g sends group1.get(0).name to sutInstance::g + + // Anonymous instance with nested reduction + testerInstance::g sends User ( + name = "Charlie", + addr = user1.addr + ) to sutInstance::g + + // Collection indexing with another data use + testerInstance::g sends group1.get(index1) to sutInstance::g + } + + Integer index1 +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testComplexBehaviour.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testComplexBehaviour.expected new file mode 100644 index 0000000000000000000000000000000000000000..8d4d15142079f9fb3150de097f8a21d9c717f5f9 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testComplexBehaviour.expected @@ -0,0 +1,32 @@ +Package: testP + SimpleDataType: MyType + GateType: mGate + ComponentType: MyCompType + GateInstance: g + TestConfiguration: MyConfig + ComponentInstance: sutInstance + ComponentInstance: testerInstance + Connection + GateReference + GateReference + TestDescription: MyTest + BehaviourDescription + CompoundBehaviour + Block + BoundedLoopBehaviour + Block + Message + Target + DataElementUse + LocalExpression + DataElementUse + ConditionalBehaviour + Block + Message + Target + DataElementUse + Block + Stop + SimpleDataInstance: instance1 + SimpleDataType: Integer + SimpleDataInstance: ten diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testComplexBehaviour.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testComplexBehaviour.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..1ec72f0c24a2b166e436e299d73df54418eb4144 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testComplexBehaviour.tdltx @@ -0,0 +1,25 @@ +Package testP { + Type MyType + Message Gate mGate accepts MyType + Component MyCompType { + gate mGate g + } + Configuration MyConfig { + MyCompType sutInstance as SUT, + MyCompType testerInstance as Tester, + connect sutInstance::g to testerInstance::g + } + Test Description MyTest uses MyConfig { + repeat ten times { + testerInstance::g sends instance1 to sutInstance::g + } + if { + testerInstance::g receives instance1 from sutInstance::g + } else { + terminate + } + } + MyType instance1 + Type Integer + Integer ten +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testConfigurationAndBehaviour.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testConfigurationAndBehaviour.expected new file mode 100644 index 0000000000000000000000000000000000000000..fc5836327fd161d667660f85555982eac28d2de0 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testConfigurationAndBehaviour.expected @@ -0,0 +1,19 @@ +Package: testP + SimpleDataType: MyType + GateType: mGate + ComponentType: MyCompType + GateInstance: g + TestConfiguration: MyConfig + ComponentInstance: sutInstance + ComponentInstance: testerInstance + Connection + GateReference + GateReference + TestDescription: MyTest + BehaviourDescription + CompoundBehaviour + Block + Message + Target + DataElementUse + SimpleDataInstance: instance1 diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testConfigurationAndBehaviour.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testConfigurationAndBehaviour.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..57669326fd6ce83ba90c1e32f94b314aca5e2a60 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testConfigurationAndBehaviour.tdltx @@ -0,0 +1,16 @@ +Package testP { + Type MyType + Message Gate mGate accepts MyType + Component MyCompType { + gate mGate g + } + Configuration MyConfig { + MyCompType sutInstance as SUT, + MyCompType testerInstance as Tester, + connect sutInstance::g to testerInstance::g + } + Test Description MyTest uses MyConfig { + testerInstance::g sends instance1 to sutInstance::g + } + MyType instance1 +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataDefinition.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataDefinition.expected new file mode 100644 index 0000000000000000000000000000000000000000..d3ee0e700dbc9b8a7cbce78994f63172d027d4c7 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataDefinition.expected @@ -0,0 +1,12 @@ +Package: testP + SimpleDataType: MySimpleType + StructuredDataType: MyStructuredType + Member: member1 + Member: member2 + CollectionDataType: MyCollectionType + SimpleDataInstance: instance1 + StructuredDataInstance: instance2 + MemberAssignment + DataElementUse + CollectionDataInstance: instance3 + DataElementUse diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataDefinition.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataDefinition.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..d49e73d4277be9d58c7f6e60256e59055435e774 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataDefinition.tdltx @@ -0,0 +1,12 @@ +Package testP { + Type MySimpleType + Structure MyStructuredType ( + MySimpleType member1, + optional MySimpleType member2 + ) + Collection MyCollectionType of MySimpleType + + MySimpleType instance1 + MyStructuredType instance2 ( member1 = instance1 ) + MyCollectionType instance3 [ instance1 ] +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataUseAndFunctions.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataUseAndFunctions.expected new file mode 100644 index 0000000000000000000000000000000000000000..d3dffad8e862b07046f4655eacc08562192018ce --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataUseAndFunctions.expected @@ -0,0 +1,24 @@ +Package: testP + SimpleDataType: Boolean + SimpleDataType: Integer + PredefinedFunction: + + PredefinedFunction: > + SimpleDataInstance: i1 + SimpleDataInstance: i2 + GateType: mGate + ComponentType: MyCompType + GateInstance: g + TestConfiguration: MyConfig + ComponentInstance: c1Instance + ComponentInstance: c2Instance + Connection + GateReference + GateReference + TestDescription: MyTest + BehaviourDescription + CompoundBehaviour + Block + VerdictAssignment + PredefinedFunctionCall + DataElementUse + DataElementUse diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataUseAndFunctions.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataUseAndFunctions.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..57666542410027ee6dd20d8b68e91e9f20e9eea3 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testDataUseAndFunctions.tdltx @@ -0,0 +1,26 @@ +Package testP { + Type Boolean + Type Integer + + Predefined + returns Integer + Predefined > returns Boolean + + Integer i1 + Integer i2 + + Message Gate mGate accepts Integer + + Component MyCompType { + gate mGate g + } + + Configuration MyConfig { + MyCompType c1Instance as SUT, + MyCompType c2Instance as Tester, + connect c1Instance::g to c2Instance::g + } + + Test Description MyTest uses MyConfig { + set verdict to (i1 + i2) + } +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testPredefinedFunctionsAndAnnotations.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testPredefinedFunctionsAndAnnotations.expected new file mode 100644 index 0000000000000000000000000000000000000000..d6a8676099fccfbb030e68c434e3bdd528178f81 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testPredefinedFunctionsAndAnnotations.expected @@ -0,0 +1,31 @@ +Package: testP + AnnotationType: MyAnno + SimpleDataType: MyType + Comment + Annotation + PredefinedFunction: == + PredefinedFunction: and + SimpleDataType: Boolean + SimpleDataInstance: instance1 + SimpleDataInstance: instance2 + GateType: mGate + ComponentType: MyCompType + GateInstance: g + TestConfiguration: MyConfig + ComponentInstance: c1Instance + ComponentInstance: c2Instance + Connection + GateReference + GateReference + TestDescription: MyTest + BehaviourDescription + CompoundBehaviour + Block + VerdictAssignment + PredefinedFunctionCall + PredefinedFunctionCall + DataElementUse + DataElementUse + PredefinedFunctionCall + DataElementUse + DataElementUse diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testPredefinedFunctionsAndAnnotations.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testPredefinedFunctionsAndAnnotations.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..609f76faa6c82044eebb0b0b678755069b782b56 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testPredefinedFunctionsAndAnnotations.tdltx @@ -0,0 +1,29 @@ +Package testP { + Annotation MyAnno + Note : "This is a note" + @MyAnno + Type MyType + + Predefined == returns Boolean + Predefined and returns Boolean + Type Boolean + + MyType instance1 + MyType instance2 + + Message Gate mGate accepts MyType + + Component MyCompType { + gate mGate g + } + + Configuration MyConfig { + MyCompType c1Instance as SUT, + MyCompType c2Instance as Tester, + connect c1Instance::g to c2Instance::g + } + + Test Description MyTest uses MyConfig { + set verdict to ((instance1 == instance2) and (instance1 == instance1)) + } +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testProcedures.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testProcedures.expected new file mode 100644 index 0000000000000000000000000000000000000000..4d2c9a4cbc29e70e789d7dd78322e3f945ed50fe --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testProcedures.expected @@ -0,0 +1,27 @@ +Package: testP + SimpleDataType: MyType + ProcedureSignature: MySignature + ProcedureParameter: p1 + ProcedureParameter: p2 + GateType: pGate + ComponentType: MyCompType + GateInstance: g + TestConfiguration: MyConfig + ComponentInstance: sutInstance + ComponentInstance: testerInstance + Connection + GateReference + GateReference + TestDescription: MyTest + BehaviourDescription + CompoundBehaviour + Block + ProcedureCall + Target + ParameterBinding + DataElementUse + ProcedureCall + Target + ParameterBinding + DataElementUse + SimpleDataInstance: instance1 diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testProcedures.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testProcedures.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..77e994bb685645e456208fab6e2d91dae8c39140 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testProcedures.tdltx @@ -0,0 +1,18 @@ +Package testP { + Type MyType + Signature MySignature ( in MyType p1, out MyType p2 ) + Procedure Gate pGate accepts MySignature + Component MyCompType { + gate pGate g + } + Configuration MyConfig { + MyCompType sutInstance as SUT, + MyCompType testerInstance as Tester, + connect sutInstance::g to testerInstance::g + } + Test Description MyTest uses MyConfig { + testerInstance::g calls MySignature ( p1 = instance1 ) on sutInstance::g + sutInstance::g responds with MySignature ( p2 = instance1 ) to testerInstance::g + } + MyType instance1 +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testTimeAndTimers.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testTimeAndTimers.expected new file mode 100644 index 0000000000000000000000000000000000000000..69f5a0ee0358678ce525086a32c3992e0f46d0ea --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testTimeAndTimers.expected @@ -0,0 +1,26 @@ +Package: testP + Time: Second + GateType: mGate + ComponentType: MyCompType + GateInstance: g + Timer: t1 + TestConfiguration: MyConfig + ComponentInstance: c1Instance + ComponentInstance: c2Instance + Connection + GateReference + GateReference + TestDescription: MyTest + BehaviourDescription + CompoundBehaviour + Block + TimerStart + DataElementUse + Wait + DataElementUse + TimeOut + Quiescence + DataElementUse + SimpleDataInstance: one + SimpleDataInstance: two + SimpleDataInstance: five diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testTimeAndTimers.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testTimeAndTimers.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..25b9f6b01c481912f42fe7dba0edc0aa37fa0ad4 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testTimeAndTimers.tdltx @@ -0,0 +1,26 @@ +Package testP { + Time Second + + Message Gate mGate accepts Second + + Component MyCompType { + timer t1 + gate mGate g + } + + Configuration MyConfig { + MyCompType c1Instance as SUT, + MyCompType c2Instance as Tester, + connect c1Instance::g to c2Instance::g + } + + Test Description MyTest uses MyConfig { + start c1Instance::t1 for one + wait for two on c1Instance + timeout on c1Instance::t1 + quiet for five on c1Instance + } + Second one + Second two + Second five +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testVariablesAndAssignments.expected b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testVariablesAndAssignments.expected new file mode 100644 index 0000000000000000000000000000000000000000..71512258f5b98b795dc374f00489c56609962852 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testVariablesAndAssignments.expected @@ -0,0 +1,20 @@ +Package: testP + SimpleDataType: Integer + SimpleDataInstance: i1 + GateType: mGate + ComponentType: MyComp + GateInstance: g + Variable: v1 + TestConfiguration: MyConfig + ComponentInstance: c1Instance + ComponentInstance: c2Instance + Connection + GateReference + GateReference + TestDescription: MyTest + BehaviourDescription + CompoundBehaviour + Block + Assignment + VariableUse + DataElementUse diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/models/testVariablesAndAssignments.tdltx b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testVariablesAndAssignments.tdltx new file mode 100644 index 0000000000000000000000000000000000000000..6eeb495a2b71b1e8b4356568f15f61c3af7cf190 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/models/testVariablesAndAssignments.tdltx @@ -0,0 +1,21 @@ +Package testP { + Type Integer + Integer i1 + + Message Gate mGate accepts Integer + + Component MyComp { + variable Integer v1 + gate mGate g + } + + Configuration MyConfig { + MyComp c1Instance as SUT, + MyComp c2Instance as Tester, + connect c1Instance::g to c2Instance::g + } + + Test Description MyTest uses MyConfig { + c1Instance::v1 = i1 + } +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxAbstractTest.java b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxAbstractTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a4caf89b6dd9b774019b1d34ae874eb0b587d4dc --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxAbstractTest.java @@ -0,0 +1,112 @@ +package org.etsi.mts.tdl.tx.tests; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Scanner; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.ocl.xtext.completeocl.CompleteOCLStandaloneSetup; +import org.eclipse.xtext.testing.InjectWith; +import org.eclipse.xtext.testing.extensions.InjectionExtension; +import org.eclipse.xtext.testing.util.ParseHelper; +import org.eclipse.xtext.testing.validation.ValidationTestHelper; +import org.etsi.mts.tdl.Package; +import org.etsi.mts.tdl.Validator; +import org.etsi.mts.tdl.tdlPackage; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.google.inject.Inject; + +@ExtendWith(InjectionExtension.class) +@InjectWith(TDLtxInjectorProvider.class) +public abstract class TDLtxAbstractTest { + static { + org.etsi.mts.tdl.tdlPackage.eINSTANCE.getName(); + org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage.eINSTANCE.getName(); + org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage.eINSTANCE.getName(); + CompleteOCLStandaloneSetup.doSetup(); + Validator.registerValidator("model/tdl-constraints.ocl", tdlPackage.eINSTANCE); + } + + @Inject + protected ParseHelper parseHelper; + + @Inject + protected ValidationTestHelper validationHelper; + + @Inject + protected ResourceSet rs; + + public Collection dynamicTestsFromFiles() throws Exception { + List tests = new ArrayList<>(); + File modelsFolder = findModelsFolder(); + + if (modelsFolder != null && modelsFolder.exists()) { + File[] files = modelsFolder.listFiles((dir, name) -> name.endsWith(".tdltx")); + if (files != null) { + for (File file : files) { + String fileName = file.getName(); + tests.add(DynamicTest.dynamicTest("Verify: " + fileName, () -> verifySingleModel(file))); + } + } + } + return tests; + } + + protected File findModelsFolder() { + URL url = getClass().getResource("/models"); + if (url != null) { + try { return new File(url.toURI()); } catch (Exception e) {} + } + String userDir = System.getProperty("user.dir"); + File f = new File(userDir, "src/models"); + if (f.exists()) return f; + f = new File(userDir, "org.etsi.mts.tdl.tx.tests/src/models"); + if (f.exists()) return f; + return new File("plugins/org.etsi.mts.tdl.tx.tests/src/models"); + } + + protected String loadModelContent(String resourcePath) throws Exception { + try (InputStream is = getClass().getResourceAsStream(resourcePath)) { + if (is == null) { + File f = new File("src" + resourcePath); + if (f.exists()) { + //TODO: delimiters are platform specific? + try (Scanner s = new Scanner(f).useDelimiter("\\A")) { + return s.hasNext() ? s.next() : ""; + } + } + throw new RuntimeException("Model not found: " + resourcePath); + } + try (Scanner s = new Scanner(is).useDelimiter("\\A")) { + return s.hasNext() ? s.next() : ""; + } + } + } + + protected void dumpStructure(EObject obj, StringBuilder sb, int indent) { + for (int i = 0; i < indent; i++) sb.append(" "); + sb.append(obj.eClass().getName()); + + EAttribute nameAttr = (EAttribute) obj.eClass().getEStructuralFeature("name"); + if (nameAttr != null) { + Object value = obj.eGet(nameAttr); + if (value != null) sb.append(": ").append(value); + } + sb.append("\n"); + + for (EObject child : obj.eContents()) { + dumpStructure(child, sb, indent + 1); + } + } + + public abstract void verifySingleModel(File file) throws Exception; + +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxInjectorProvider.java b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxInjectorProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..04cc68638dee19651356e6ca20e0267b78883e9e --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxInjectorProvider.java @@ -0,0 +1,31 @@ +package org.etsi.mts.tdl.tx.tests; + +import com.google.inject.Injector; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.xtext.testing.IInjectorProvider; +import org.etsi.mts.tdl.tdlPackage; +import org.etsi.mts.tdl.TDLtxStandaloneSetup; + +public class TDLtxInjectorProvider implements IInjectorProvider { + + protected Injector injector; + + @Override + public Injector getInjector() { + if (injector == null) { + if (!EPackage.Registry.INSTANCE.containsKey(tdlPackage.eNS_URI)) { + EPackage.Registry.INSTANCE.put(tdlPackage.eNS_URI, tdlPackage.eINSTANCE); + } + if (!EPackage.Registry.INSTANCE.containsKey("http://www.etsi.org/spec/TDL/1.3.1/structured")) { + EPackage.Registry.INSTANCE.put("http://www.etsi.org/spec/TDL/1.3.1/structured", + org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage.eINSTANCE); + } + if (!EPackage.Registry.INSTANCE.containsKey("http://www.etsi.org/spec/TDL/1.3.1/configurations")) { + EPackage.Registry.INSTANCE.put("http://www.etsi.org/spec/TDL/1.3.1/configurations", + org.etsi.mts.tdl.extendedconfigurations.ExtendedConfigurationsPackage.eINSTANCE); + } + this.injector = new TDLtxStandaloneSetup().createInjectorAndDoEMFRegistration(); + } + return injector; + } +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxInjectorProviderGenerated.java b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxInjectorProviderGenerated.java new file mode 100644 index 0000000000000000000000000000000000000000..12776d61c2fcee28e2033a413d8de97ebc9a6bbf --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxInjectorProviderGenerated.java @@ -0,0 +1,71 @@ +/* + * generated by Xtext 2.40.0 + */ +package org.etsi.mts.tdl.tx.tests; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import org.eclipse.xtext.testing.GlobalRegistries; +import org.eclipse.xtext.testing.GlobalRegistries.GlobalStateMemento; +import org.eclipse.xtext.testing.IInjectorProvider; +import org.eclipse.xtext.testing.IRegistryConfigurator; +import org.etsi.mts.tdl.TDLtxRuntimeModule; +import org.etsi.mts.tdl.TDLtxStandaloneSetup; + +public class TDLtxInjectorProviderGenerated implements IInjectorProvider, IRegistryConfigurator { + + protected GlobalStateMemento stateBeforeInjectorCreation; + protected GlobalStateMemento stateAfterInjectorCreation; + protected Injector injector; + + static { + GlobalRegistries.initializeDefaults(); + } + + @Override + public Injector getInjector() { + if (injector == null) { + this.injector = internalCreateInjector(); + stateAfterInjectorCreation = GlobalRegistries.makeCopyOfGlobalState(); + } + return injector; + } + + protected Injector internalCreateInjector() { + return new TDLtxStandaloneSetup() { + @Override + public Injector createInjector() { + return Guice.createInjector(createRuntimeModule()); + } + }.createInjectorAndDoEMFRegistration(); + } + + protected TDLtxRuntimeModule createRuntimeModule() { + // make it work also with Maven/Tycho and OSGI + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=493672 + // allows for bindClassLoaderToInstance to get the class loader of the bundle + // containing the instance of the injector provider (possibly inherited) + return new TDLtxRuntimeModule() { + @Override + public ClassLoader bindClassLoaderToInstance() { + return TDLtxInjectorProviderGenerated.this.getClass() + .getClassLoader(); + } + }; + } + + @Override + public void restoreRegistry() { + stateBeforeInjectorCreation.restoreGlobalState(); + stateBeforeInjectorCreation = null; + } + + @Override + public void setupRegistry() { + stateBeforeInjectorCreation = GlobalRegistries.makeCopyOfGlobalState(); + if (injector == null) { + getInjector(); + } + stateAfterInjectorCreation.restoreGlobalState(); + } +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxParsingTest.java b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxParsingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..73ca4a5894f593ffac8d330ded0da5ecb8dbab61 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxParsingTest.java @@ -0,0 +1,79 @@ +package org.etsi.mts.tdl.tx.tests; + +import java.io.File; +import java.nio.file.Files; +import java.util.Collection; + +import org.eclipse.emf.common.util.URI; +import org.etsi.mts.tdl.Package; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; + +//Generated by Xtext +//@InjectWith(TDLtxInjectorProviderGenerated.class) +public class TDLtxParsingTest extends TDLtxAbstractTest { + + + @TestFactory + public Collection dynamicTestsFromFiles() throws Exception { + return super.dynamicTestsFromFiles(); + } + + + @Test + public void verifyLoadModelAttributes() throws Exception { + Package result = parseHelper.parse(loadModelContent("/models/loadModel.tdltx")); + Assertions.assertNotNull(result); + Assertions.assertEquals("testP", result.getName()); + } + +// @Test + public void verifyAllModels() throws Exception { + File modelsFolder = findModelsFolder(); + if (modelsFolder != null && modelsFolder.exists()) { + File[] files = modelsFolder.listFiles((dir, name) -> name.endsWith(".tdltx")); + if (files != null) { + for (File file : files) { + verifySingleModel(file); + } + } + } + + } + + @Override + public void verifySingleModel(File file) throws Exception { + String fileName = file.getName(); + System.out.println("Verifying: "+fileName); + String content = loadModelContent("/models/" + fileName); + URI uri = URI.createFileURI(file.getAbsolutePath()); +// Package result = parseHelper.parse(content, uri, rs); + Package result = parseHelper.parse(content); + + Assertions.assertNotNull(result, "Parser returned null for " + fileName); + Assertions.assertTrue(result.eResource().getErrors().isEmpty(), + "Syntax errors in " + fileName + ": " + result.eResource().getErrors()); + + //NOTE: this requires manual registration of validator when running in eclipse, completeOCL initialisation when running in maven + validationHelper.assertNoErrors(result); + + StringBuilder structure = new StringBuilder(); + dumpStructure(result, structure, 0); + String actualStructure = structure.toString(); + + File expectedFile = new File(file.getParentFile(), fileName.replace(".tdltx", ".expected")); + if (expectedFile.exists()) { + String expectedStructure = new String(Files.readAllBytes(expectedFile.toPath())).replace("\r\n", "\n"); + Assertions.assertEquals(expectedStructure, actualStructure, + "Structural mismatch detected in " + fileName); + } else { + // Record baseline if not present (only in development environment) + Files.write(expectedFile.toPath(), actualStructure.getBytes()); + System.out.println("Recorded baseline for " + fileName); + } + + } + +} diff --git a/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxSerialisationTest.java b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxSerialisationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..decc858708bb874db826ab85e19f0588eabed004 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.tests/src/org/etsi/mts/tdl/tx/tests/TDLtxSerialisationTest.java @@ -0,0 +1,86 @@ +package org.etsi.mts.tdl.tx.tests; + +import java.io.File; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.Collection; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.etsi.mts.tdl.Package; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; + +//Generated by Xtext +//@InjectWith(TDLtxInjectorProviderGenerated.class) +public class TDLtxSerialisationTest extends TDLtxAbstractTest { + + + @TestFactory + public Collection dynamicTestsFromFiles() throws Exception { + return super.dynamicTestsFromFiles(); + } + + + @Test + public void verifyLoadModelAttributes() throws Exception { + Package result = parseHelper.parse(loadModelContent("/models/loadModel.tdltx")); + Assertions.assertNotNull(result); + Assertions.assertEquals("testP", result.getName()); + } + +// @Test + public void verifyAllModels() throws Exception { + File modelsFolder = findModelsFolder(); + if (modelsFolder != null && modelsFolder.exists()) { + File[] files = modelsFolder.listFiles((dir, name) -> name.endsWith(".tdltx")); + if (files != null) { + for (File file : files) { + verifySingleModel(file); + } + } + } + + } + + @Override + public void verifySingleModel(File file) throws Exception { + String extension = "tdltx"; + String fileName = file.getName(); + if (fileName.endsWith(".tdltx."+extension)) { + return; + } + System.out.println("Verifying: "+fileName); + String content = loadModelContent("/models/" + fileName); + URI uri = URI.createFileURI(file.getAbsolutePath()); +// Package result = parseHelper.parse(content, uri, rs); + Package result = parseHelper.parse(content); + + Assertions.assertNotNull(result, "Parser returned null for " + fileName); + Assertions.assertTrue(result.eResource().getErrors().isEmpty(), + "Syntax errors in " + fileName + ": " + result.eResource().getErrors()); + + //NOTE: this requires manual registration of validator when running in eclipse, completeOCL initialisation when running in maven + validationHelper.assertNoErrors(result); + + URI targetURI = URI.createURI(uri.toString()+"."+extension); +// XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class); +// resourceSet = rs; + Resource tr = rs.createResource(targetURI); + + tr.getContents().add(EcoreUtil.copy(result)); + try { + EcoreUtil.resolveAll(tr); + tr.save(OutputStream.nullOutputStream(), null); + } catch (Exception e1) { + System.err.println(" Translation: "+e1.getMessage()); + //e1.printStackTrace(); + Assertions.fail(e1.getMessage(), e1); + //TODO: provide an error dialog, fall back to XF, indicate approximate location based on error message / details + } + } + +} diff --git a/plugins/org.etsi.mts.tdl.tx.ui/.classpath b/plugins/org.etsi.mts.tdl.tx.ui/.classpath index f208d6d3928b4cca50476cc9df40e0a34b3cd264..2f9d36fdfabd47830d7368f2c184d13bf7d7530d 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/.classpath +++ b/plugins/org.etsi.mts.tdl.tx.ui/.classpath @@ -1,10 +1,6 @@ - - - - - + diff --git a/plugins/org.etsi.mts.tdl.tx.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.etsi.mts.tdl.tx.ui/.settings/org.eclipse.jdt.core.prefs index a58ebdcad300d0a088dcbd63941d2c89e78a4f98..1e0cb16bbc76c98cc42fff6b95cc023b7eb74830 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/.settings/org.eclipse.jdt.core.prefs +++ b/plugins/org.etsi.mts.tdl.tx.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -12,4 +12,4 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=11 +org.eclipse.jdt.core.compiler.source=21 diff --git a/plugins/org.etsi.mts.tdl.tx.ui/META-INF/MANIFEST.MF b/plugins/org.etsi.mts.tdl.tx.ui/META-INF/MANIFEST.MF index 87291d9223a84042937e355aea1ab7a00391571f..cc62f1dd5e1018ff4080e67fd2687cd68c92608d 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/META-INF/MANIFEST.MF +++ b/plugins/org.etsi.mts.tdl.tx.ui/META-INF/MANIFEST.MF @@ -9,11 +9,12 @@ Bundle-ActivationPolicy: lazy Require-Bundle: org.etsi.mts.tdl.tx, org.etsi.mts.tdl.tx.ide, org.etsi.mts.tdl.model, + org.etsi.mts.tdl.common, org.eclipse.xtext.ui, org.eclipse.xtext.ui.shared, org.eclipse.xtext.ui.codetemplates.ui, - org.eclipse.ui.editors;bundle-version="3.5.0", - org.eclipse.ui.ide;bundle-version="3.5.0", + org.eclipse.ui.editors;bundle-version="3.14.300", + org.eclipse.ui.ide;bundle-version="3.18.500", org.eclipse.ui, org.eclipse.compare, org.eclipse.xtext.builder, @@ -21,11 +22,9 @@ Require-Bundle: org.etsi.mts.tdl.tx, org.eclipse.xtend.lib, org.eclipse.core.runtime, org.eclipse.core.resources, - org.eclipse.pde.core, - org.eclipse.ui.forms, - org.etsi.mts.tdl.openapi2tdl.next + org.eclipse.ui.forms Import-Package: org.apache.log4j -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.etsi.mts.tdl.tx.ui.internal, org.etsi.mts.tdl.ui.contentassist, org.etsi.mts.tdl.ui.outline, diff --git a/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_empty.png b/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..fddcb8c4edba947a86eb4892ab4fc90dc31922a1 Binary files /dev/null and b/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_empty.png differ diff --git a/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_to.png b/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_to.png new file mode 100644 index 0000000000000000000000000000000000000000..eb97ea65df6ddaad1aa19d35e43e0b56d14065b9 Binary files /dev/null and b/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_to.png differ diff --git a/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_tpd.png b/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_tpd.png new file mode 100644 index 0000000000000000000000000000000000000000..4554d18d2b550cdd53202621f8b56a1b6da51d50 Binary files /dev/null and b/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_tpd.png differ diff --git a/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_tri.png b/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_tri.png new file mode 100644 index 0000000000000000000000000000000000000000..fddcb8c4edba947a86eb4892ab4fc90dc31922a1 Binary files /dev/null and b/plugins/org.etsi.mts.tdl.tx.ui/icons/project_template_tri.png differ diff --git a/plugins/org.etsi.mts.tdl.tx.ui/plugin.xml b/plugins/org.etsi.mts.tdl.tx.ui/plugin.xml index 7968b6524b8f34315db1fd9af9ed90b7b4043cc6..5e31523eafa307622cdcb540c828a25b75a3aa4e 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/plugin.xml +++ b/plugins/org.etsi.mts.tdl.tx.ui/plugin.xml @@ -9,7 +9,7 @@ default="true" extensions="tdltx" id="org.etsi.mts.tdl.TDLtx" - name="TDLtx Editor"> + name="TDL Textual Editor"> @@ -87,7 +87,7 @@ + name="TDL Textual"> + name="TDL Textual"> @@ -122,7 +122,7 @@ point="org.eclipse.ui.keywords"> + label="TDL Textual"/> @@ -216,7 +216,7 @@ base-type="org.eclipse.core.runtime.text" file-extensions="tdltx" id="org.etsi.mts.tdl.TDLtx.contenttype" - name="TDLtx File" + name="TDL Textual File" priority="normal"> @@ -237,21 +237,21 @@ @@ -292,6 +292,17 @@ + + + + + + + extensions="tdltx" label="TDL Textual Compare"> - + @@ -480,7 +491,7 @@ --> + tooltip="Create a new TDL Textual project"> @@ -491,13 +502,13 @@ - + @@ -530,7 +541,7 @@ --> + tooltip="Create a new TDL Textual file"> diff --git a/plugins/org.etsi.mts.tdl.tx.ui/plugin.xml_gen b/plugins/org.etsi.mts.tdl.tx.ui/plugin.xml_gen deleted file mode 100644 index c390f8d59246ea8d4cdead302254cb5187a0685d..0000000000000000000000000000000000000000 --- a/plugins/org.etsi.mts.tdl.tx.ui/plugin.xml_gen +++ /dev/null @@ -1,535 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/TDLtxUiModule.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/TDLtxUiModule.java index f4feae09d355be031003666023636aeb85805978..4de3bf2b3ef7e8ecb00c226b9d36fd7da1679800 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/TDLtxUiModule.java +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/TDLtxUiModule.java @@ -4,9 +4,17 @@ package org.etsi.mts.tdl.ui; import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalPostProcessor; +import org.eclipse.xtext.ui.editor.contentassist.IContentProposalProvider; import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider; +import org.eclipse.xtext.ui.editor.syntaxcoloring.AbstractAntlrTokenToAttributeIdMapper; +import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfiguration; +import org.eclipse.xtext.ui.editor.syntaxcoloring.ISemanticHighlightingCalculator; +import org.etsi.mts.tdl.ui.highlighting.TDLtxHighlightingCalculator; +import org.etsi.mts.tdl.ui.highlighting.TDLtxHighlightingConfiguration; +import org.etsi.mts.tdl.ui.highlighting.TDLtxTokenToAttributeIdMapper; import org.etsi.mts.tdl.ui.hover.TDLtxHoverProvider; - +import org.etsi.mts.tdl.ui.contentassist.DefaultCompletionProposalPostProcessor; /** * Use this class to register components to be used within the Eclipse IDE. */ @@ -19,7 +27,40 @@ public class TDLtxUiModule extends AbstractTDLtxUiModule { public Class bindIEObjectHoverProvider() { return TDLtxHoverProvider.class; } - + + //@Override + public Class bindIHighlightingConfiguration() { + return TDLtxHighlightingConfiguration.class; + } + + public Class bindAbstractAntlrTokenToAttributeIdMapper() { + return TDLtxTokenToAttributeIdMapper.class; + } + + public Class bindISemanticHighlightingCalculator() { + return TDLtxHighlightingCalculator.class; + } + + @Override + public Class bindICompletionProposalPostProcessor() { + return super.bindICompletionProposalPostProcessor(); +// return DefaultCompletionProposalPostProcessor.class; + } + +// @Override +// public void configure(Binder binder) { +// super.configure(binder); +// binder.bind(TokenTypeToStringMapper.class).to(TDLtxTokenToAttributeIdMapper.class); +// binder.bind(Predicate.class).annotatedWith(Names.named("ePackageUriFilter")).toInstance(new Predicate() { +//// @Override +// public boolean apply(String input) { +// if (input.startsWith("http://www.eclipse.org/emf") && !input.equals(EcorePackage.eNS_URI)) +// return true; +// return false; +// } +// }); +// } + // @Override // public Class bindIResourceSetProvider() { // //potential optimisation based on https://alexruizlog.blogspot.com/2012/07/make-your-xtext-based-editor-300-times.html?m=1#! diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/DefaultCompletionProposalPostProcessor.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/DefaultCompletionProposalPostProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..e5cfc6f388cb168b9b3ba18698328d3aced09438 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/DefaultCompletionProposalPostProcessor.java @@ -0,0 +1,28 @@ +package org.etsi.mts.tdl.ui.contentassist; + +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal; +import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalPostProcessor; + +/** + * @author Sebastian Zarnekow - Initial contribution and API + */ +public class DefaultCompletionProposalPostProcessor implements ICompletionProposalPostProcessor { + + @Override + public ICompletionProposal[] postProcess(ICompletionProposal[] proposals) { + if (proposals.length == 1) { + if (proposals[0] instanceof ConfigurableCompletionProposal) { + ConfigurableCompletionProposal proposal = (ConfigurableCompletionProposal) proposals[0]; + if (proposal.isAutoInsertable() && proposal.getReplaceContextLength() > proposal.getReplacementLength()) { + proposal.setAutoInsertable(false); + } + } + } + for (ICompletionProposal proposal : proposals) { + System.out.println(" "+proposal); + } + return proposals; + } + +} diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/PropertyPage.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/PropertyPage.java new file mode 100644 index 0000000000000000000000000000000000000000..8a61f8ae9d14e395dbd9ed91771a43eec2a586ce --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/PropertyPage.java @@ -0,0 +1,133 @@ +package org.etsi.mts.tdl.ui.contentassist; + +import java.util.Arrays; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.IWorkbenchPropertyPage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +public class PropertyPage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + public static final String TRACE_UI = "TraceUI"; + + public static final String PREFERENCE_SCOPE = "org.etsi.mts.tdl.tx.ui"; + + private static final List REQUIRED_SETTINGS = Arrays.asList(new String[] { /* TODO */ }); + + protected IAdaptable element; + + protected Map fields = new Hashtable(); + + public PropertyPage() { + super(GRID); + } + +// @Override + public IAdaptable getElement() { + return element; + } + +// @Override + public void setElement(IAdaptable element) { + this.element = element; + } + + @Override + protected IPreferenceStore doGetPreferenceStore() { + ProjectScope ps = new ProjectScope((IProject) this.element); + ScopedPreferenceStore scopedStore = new ScopedPreferenceStore(ps, PREFERENCE_SCOPE); + scopedStore.setDefault(TRACE_UI, false); + return scopedStore; + } + + @Override + protected void initialize() { + for (FieldEditor e : fields.keySet()) { + String value = getPreferenceStore().getString(e.getPreferenceName()); + fields.put(e, value); + initialize(e.getPreferenceName(), value, e); + } + super.initialize(); + } + + protected void initialize(String name, String value, FieldEditor e) { + if (name.equals(TRACE_UI)) { + } + } + + @Override + protected void addField(FieldEditor editor) { + super.addField(editor); + fields.put(editor, ""); + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + super.propertyChange(event); + if (event.getProperty().equals(FieldEditor.VALUE)) { + FieldEditor e = (FieldEditor) event.getSource(); + + String name = e.getPreferenceName(); + Object valueObj = event.getNewValue(); + String value = valueObj.toString(); + + fields.put(e, value); + + initialize(name, value, e); + + checkState(); + } + } + + @Override + protected void checkState() { + setErrorMessage(null); + super.checkState(); + } + + @Override + protected void createFieldEditors() { + + Composite parent = getFieldEditorParent(); + BooleanFieldEditor traceUI = new BooleanFieldEditor(TRACE_UI, "Trace Content Assist", parent); + addField(traceUI); + + // TODO + } + + private boolean isValid(FieldEditor e) { + String name = e.getPreferenceName(); + String value = fields.get(e); + + if (REQUIRED_SETTINGS.contains(name)) { + if (value.isEmpty()) { + setErrorMessage(String.format("%s must be selected!", e.getLabelText())); + return false; + } + } + + return true; + } + + @Override + public void init(IWorkbench workbench) { + setPreferenceStore(new ScopedPreferenceStore(InstanceScope.INSTANCE, PREFERENCE_SCOPE)); + setDescription("Content Assist Configuration"); + } + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/TDLtxProposalProvider.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/TDLtxProposalProvider.java index f68929f5fdd3df12140c5f0acc668807c9a3e9d9..fc8ad5274f70197676ed9490d0a25547f82806f0 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/TDLtxProposalProvider.java +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/contentassist/TDLtxProposalProvider.java @@ -3,16 +3,50 @@ */ package org.etsi.mts.tdl.ui.contentassist; +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.viewers.StyledString; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.eclipse.xtext.AbstractElement; +import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.Assignment; +import org.eclipse.xtext.CrossReference; +import org.eclipse.xtext.EcoreUtil2; +import org.eclipse.xtext.GrammarUtil; +import org.eclipse.xtext.ParserRule; import org.eclipse.xtext.RuleCall; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.ui.editor.contentassist.CompletionProposalComputer; +import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal; import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext; import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor; +import org.eclipse.xtext.util.Strings; +import org.etsi.mts.tdl.CastDataUse; +import org.etsi.mts.tdl.CollectionDataType; import org.etsi.mts.tdl.Connection; +import org.etsi.mts.tdl.DataElementUse; +import org.etsi.mts.tdl.DataInstance; +import org.etsi.mts.tdl.DataType; +import org.etsi.mts.tdl.ElementImport; +import org.etsi.mts.tdl.FormalParameter; +import org.etsi.mts.tdl.Function; import org.etsi.mts.tdl.Member; +import org.etsi.mts.tdl.MemberAssignment; +import org.etsi.mts.tdl.MemberReference; import org.etsi.mts.tdl.Message; -import org.etsi.mts.tdl.Target; +import org.etsi.mts.tdl.NamedElement; +import org.etsi.mts.tdl.PackageableElement; +import org.etsi.mts.tdl.Parameter; +import org.etsi.mts.tdl.ParameterBinding; +import org.etsi.mts.tdl.SimpleDataType; import org.etsi.mts.tdl.StructuredDataInstance; import org.etsi.mts.tdl.StructuredDataType; @@ -21,66 +55,653 @@ import org.etsi.mts.tdl.StructuredDataType; * on how to customize the content assistant. */ public class TDLtxProposalProvider extends AbstractTDLtxProposalProvider { + public static boolean traceCompletions = false; + public static boolean traceCompletionsInUI = false; + + //super patterns + //rule: empty + //reference assignment: lookupCrossReference + //element containment: completeRuleCall + public static boolean superRule = false; + public static boolean superReference = false; + public static boolean superContainment = false; + private static String trace = ""; + + + private void trace(ContentAssistContext contentAssistContext, String methodName) { + System.out.println(methodName); + System.out.println(" context: "+NodeModelUtils.findActualNodeFor(contentAssistContext.getCurrentModel()).getText().trim()+" : "+contentAssistContext.getCurrentModel().eClass().getName()); + System.out.println(" replace: "+contentAssistContext.getReplaceRegion()); + trace += "\n"+methodName; + trace += "\n"+" context: "+NodeModelUtils.findActualNodeFor(contentAssistContext.getCurrentModel()).getText().trim()+" : "+contentAssistContext.getCurrentModel().eClass().getName(); + trace += "\n"+" replace: "+contentAssistContext.getReplaceRegion(); + } + + private void preTrace(Assignment assignment, ContentAssistContext contentAssistContext) { + if (traceCompletions) { + String methodName = getName(assignment); + trace(contentAssistContext, "--A: "+methodName); + } + } + + private String getName(Assignment assignment) { + ParserRule parserRule = GrammarUtil.containingParserRule(assignment); + String methodName = "complete" + Strings.toFirstUpper(parserRule.getName()) + "_" + + Strings.toFirstUpper(assignment.getFeature()); + return methodName; + } + + private void preTrace(RuleCall ruleCall, ContentAssistContext contentAssistContext) { + if (traceCompletions) { + String methodName = getName(ruleCall); + trace(contentAssistContext, "--R: "+methodName); + } + } + + private String getName(RuleCall ruleCall) { + AbstractRule calledRule = ruleCall.getRule(); + String methodName = "complete_" + calledRule.getName(); + return methodName; + } + + private void postTrace(ICompletionProposalAcceptor acceptor) { + if (traceCompletions) { + Object proposals = getProposals(acceptor); + System.out.println(" proposals: "+proposals); + List proposalDescriptions = ((Collection)proposals).stream() + .map(e->(ConfigurableCompletionProposal) e) + .sorted(ConfigurableCompletionProposal::compareTo) + .map(ICompletionProposal::getDisplayString) + .filter(e -> !e.startsWith("--")).toList(); + trace += "\n proposals: "+proposals; + trace += "\n "+String.join("\n ", proposalDescriptions); + + } + } + + private void traceUI(ContentAssistContext contentAssistContext, ICompletionProposalAcceptor acceptor, + String name) { + ICompletionProposal proposal = createCompletionProposal("--TRACE", new StyledString("---TRACE"), null, 1000000001, "", contentAssistContext); + if (proposal != null) { //TODO: why is this null all of a sudden? + ((ConfigurableCompletionProposal)proposal).setAdditionalProposalInfo(trace); + +// Collection proposals = (Collection) getProposals(acceptor); +// List proposalDescriptions = proposals.stream().map(ICompletionProposal::getDisplayString).filter(e -> !e.startsWith("--")).toList(); +// ICompletionProposal proposal = createCompletionProposal(name, new StyledString(name), null, 1000000001, "", contentAssistContext); +// ((ConfigurableCompletionProposal)proposal).setAdditionalProposalInfo(String.join("\n", proposalDescriptions)); + acceptor.accept(proposal); + } + } + + private Object getProposals(ICompletionProposalAcceptor acceptor) { + try { + CompletionProposalComputer completionProposalComputer; + if (acceptor instanceof NullSafeCompletionProposalAcceptor) { + completionProposalComputer = (CompletionProposalComputer)((NullSafeCompletionProposalAcceptor) acceptor).getDelegate(); + } else { + completionProposalComputer = (CompletionProposalComputer) acceptor; + } + Field proposalsField = completionProposalComputer.getClass().getDeclaredField("proposals"); + proposalsField.setAccessible(true); + Object proposals = proposalsField.get(completionProposalComputer); + return proposals; + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + //------------------------------------------------------------------------------------------------------ + @Override - public void completeMemberAssignment_Member(EObject model, Assignment assignment, ContentAssistContext context, + public void createProposals(ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, PropertyPage.PREFERENCE_SCOPE); + boolean traceEnabled = store.getBoolean(PropertyPage.TRACE_UI); + traceCompletions = traceEnabled; + traceCompletionsInUI = traceEnabled; + superRule = true; + superReference = true; + superContainment = true; + trace = ""; + super.createProposals(context, acceptor); + if (traceCompletionsInUI) { + traceUI(context, acceptor, trace); + } + } + + @Override + public void completeRuleCall(RuleCall ruleCall, ContentAssistContext contentAssistContext, + ICompletionProposalAcceptor acceptor) { + preTrace(ruleCall, contentAssistContext); + super.completeRuleCall(ruleCall, contentAssistContext, acceptor); + postTrace(acceptor); + if (traceCompletionsInUI) { + String name = "--R: "+getName(ruleCall) + " : "+contentAssistContext.getCurrentModel().eClass().getName(); + //traceUI(contentAssistContext, acceptor, name); + } + } + + @Override + public void completeAssignment(Assignment assignment, ContentAssistContext contentAssistContext, + ICompletionProposalAcceptor acceptor) { + preTrace(assignment, contentAssistContext); + super.completeAssignment(assignment, contentAssistContext, acceptor); + postTrace(acceptor); + if (traceCompletionsInUI) { + String name = "--A: "+getName(assignment) + " : "+contentAssistContext.getCurrentModel().eClass().getName(); + //traceUI(contentAssistContext, acceptor, name); + } + } + + //---------------------------------------------------------------------------------------------------- + + @Override + public void complete_DataUse(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding) { +// complete_ParameterBinding(model, ruleCall, context, acceptor); + //TODO: what are the implications here? + return; + } + //TODO: does this make sense + //super: empty + if (superRule) + super.complete_DataUse(model, ruleCall, context, acceptor); + } + + @Override + public void completeDataUse_Function(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model instanceof MemberReference) { + return; //this skips all the predefined functions, should instead be demoted + } + //super: lookupCrossReference + if (superReference) + super.completeDataUse_Function(model, assignment, context, acceptor); + } + + @Override + public void complete_CheckFragment(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + //super: empty + if (superRule) + super.complete_CheckFragment(model, ruleCall, context, acceptor); + } + + @Override + public void complete_DataUseWrapped(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding) { + return; + } + //super: empty + if (superRule) + super.complete_DataUse(model, ruleCall, context, acceptor); + } + + @Override + public void complete_ParameterBinding(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + //super: empty + if (superRule) + super.complete_ParameterBinding(model, ruleCall, context, acceptor); + } + + @Override + public void completeParameterBinding_Parameter(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + //TODO: what is this? +// lookupCrossReference(((CrossReference)assignment.getTerminal()), context, acceptor); +// completeRuleCall(((RuleCall)assignment.getTerminal()), context, acceptor); + + if (model instanceof DataElementUse) { + completeMemberReferenceForDataUse(model, context, acceptor, "", " = ?", " : assign to member"); + return; + } + //TODO: what is this? + //after comma +// System.out.println(assignment); + + //super: lookupCrossReference + if (superReference) + super.completeParameterBinding_Parameter(model, assignment, context, acceptor); + } + + @Override + public void completeParameterBindingFragment_Argument(EObject model, Assignment assignment, + ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + //super: completeRuleCall + //if (superContainment) + //super.completeParameterBindingFragment_Argument(model, assignment, context, acceptor); + } + + @Override + public void completeParameterBinding_DataUse(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + + //TODO: relevant? + if (model instanceof ParameterBinding) { +// var pb = ((ParameterBinding) model); +// var type = pb.getParameter().getDataType(); +// completeAssignment(model, context, acceptor, type); + + return; + } + + //super: completeRuleCall + if (superContainment) + super.completeParameterBinding_DataUse(model, assignment, context, acceptor); + } + + @Override + public void complete_ParameterBindingFragment(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - // TODO Auto-generated method stub - //super.completeMemberAssignment_Member(model, assignment, context, acceptor); - // compute the plain proposal - for (Member m : ((StructuredDataType) - ((StructuredDataInstance)model).getDataType()).allMembers()) { - acceptor.accept(createCompletionProposal(m.getName(), context)); + //TODO: what is this + //before comma!! context: current element +// model.eContainer() instanceof +// if (model instanceof DataElementUse) { +// for (Member m : ((StructuredDataType)((DataElementUse) model.eContainer()).resolveDataType()).allMembers()) { +// acceptor.accept(createCompletionProposal(m.getName(), new StyledString(m.getName()), getImage(m), 1000, "", context)); +// } +// } + if (model instanceof ParameterBinding) { + var pb = ((ParameterBinding) model); + var type = pb.getParameter().getDataType(); + //TODO: add anything that contains string fields? + //start with + completeAssignment(model, context, acceptor, type); + } + if ((model instanceof DataElementUse)) { + if (!context.getPrefix().equals("(")) { + completeMemberReferenceForDataUse(model, context, acceptor, "(", " = ?)", " : assign to member"); + } else { + completeMemberReferenceForDataUse(model, context, acceptor, "", "", ""); + } } + //super: empty + if (superRule) + super.complete_ParameterBindingFragment(model, ruleCall, context, acceptor); + } + + @Override + public void complete_MemberAssignment(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + completeMemberReferenceForDataUse(model, context, acceptor, "", " = ?", " : assign to member"); + //super: empty + if (superRule) + super.complete_MemberAssignment(model, ruleCall, context, acceptor); + } + + @Override + public void completeMemberAssignment_Member(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + //super: lookupCrossReference + if (superReference) + super.completeMemberAssignment_Member(model, assignment, context, acceptor); + + //TODO: what is this? + // compute the plain proposal +// for (Member m : ((StructuredDataType) +// ((StructuredDataInstance)model).getDataType()).allMembers()) { +// acceptor.accept(createCompletionProposal(m.getName(), context)); +// } // Create and register the completion proposal: // The proposal may be null as the createCompletionProposal(..) // methods check for valid prefixes and terminal token conflicts. // The acceptor handles null-values gracefully. } + + + @Override + public void completeMemberAssignment_MemberSpec(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model instanceof MemberAssignment) { + var ma = ((MemberAssignment) model); + var type = ma.getMember().getDataType(); + completeAssignment(model, context, acceptor, type); + } + if (model instanceof StructuredDataInstance) { + //TODO: handle + } + //super: completeRuleCall + if (superContainment) + super.completeMemberAssignment_MemberSpec(model, assignment, context, acceptor); + } + + private void completeAssignment(EObject model, ContentAssistContext context, ICompletionProposalAcceptor acceptor, DataType type) { + List namedElements = getAllElementsOfType(model, NamedElement.class); + + for (NamedElement ne : namedElements) { + boolean accept = false; + //TODO: priorities + if (ne instanceof DataInstance && ((DataInstance)ne).getDataType().conformsTo(type)) { + accept = true; + } else if (ne instanceof DataType && ((DataType) ne).conformsTo(type)) { + //accept = true; + if (ne instanceof SimpleDataType) { + + } else { + String prefix = "new "; + String suffix = "()"; + if (ne instanceof CollectionDataType) { + suffix = "[]"; + } + acceptor.accept(createCompletionProposal(prefix+ne.getName()+suffix, new StyledString(prefix+ne.getName()+suffix).append(" : new instance of type", StyledString.DECORATIONS_STYLER), getImage(ne), 1000, "", context)); + } + } else if (ne instanceof Function && ((Function) ne).getReturnType().conformsTo(type)) { + accept = true; + } else if (ne instanceof FormalParameter && EcoreUtil2.isAncestor(EcoreUtil2.getContainerOfType(model, PackageableElement.class), ne)) { + accept = true; + } else if (ne instanceof Parameter && ((Parameter) ne).getDataType().conformsTo(type) && ne.container() instanceof StructuredDataType) { + StructuredDataType dt = ((StructuredDataType) ne.container()); + List compatibleDataInstances = getAllElementsOfType(model, StructuredDataInstance.class).stream() + .map(sdi -> (StructuredDataInstance) sdi) + .filter(sdi -> sdi.getDataType().conformsTo(dt)) + .toList(); + //TODO: also consider where dt is used recursively via members / extensions? + for (StructuredDataInstance sdi : compatibleDataInstances) { + acceptor.accept(createCompletionProposal(sdi.getName()+"."+ne.getName(), new StyledString(sdi.getName()+"."+ne.getName()).append(" : in "+sdi.getQualifiedName(), StyledString.DECORATIONS_STYLER), getImage(ne), 900, "", context)); + } + } + if (accept) { + acceptor.accept(createCompletionProposal(ne.getName(), new StyledString(ne.getName()), getImage(ne), 1000, "", context)); + } + } + } + private List getAllElementsOfType(EObject model, Class type) { + List namedElements = EcoreUtil2.getAllContentsOfType(model.eResource(), type); + //TODO: filter imported if not all? + EcoreUtil2.getAllContentsOfType(model.eResource(), ElementImport.class).stream() + .map(e -> e.getImportedPackage()) + .forEach(e -> namedElements.addAll(EcoreUtil2.getAllContentsOfType(e.eResource(), type))); + return namedElements; + } + + @Override + public void complete_ParameterReductionFragment(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + //super: empty + if (superRule) + super.complete_ParameterReductionFragment(model, ruleCall, context, acceptor); + } + + @Override + public void completeParameterReductionFragment_Reduction(EObject model, Assignment assignment, + ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + //super: completeRuleCall + if (superContainment) + super.completeParameterReductionFragment_Reduction(model, assignment, context, acceptor); + } + + @Override + public void complete_ReductionFragment(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (!context.getPrefix().equals("(")) { + completeMemberReferenceForDataUse(model, context, acceptor, ".", "", " : access member"); + } + //super: empty + if (superRule) + super.complete_ReductionFragment(model, ruleCall, context, acceptor); + } + + @Override + public void completeReductionFragment_Reduction(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + //TODO: handle better + //completeMemberReferenceForDataUse(model, context, acceptor, "", "", " : access member"); + //super: completeRuleCall +// if (superContainment) +// super.completeReductionFragment_Reduction(model, assignment, context, acceptor); + + } + + @Override + public void complete_MemberReference(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model.eContainer() instanceof ParameterBinding) { +// return; + } + if (model.eContainer() instanceof MemberAssignment) { +// return; + } + if (model instanceof DataElementUse) { + return; + } + EObject semanticElement = context.getCurrentNode().getSemanticElement(); + if (semanticElement instanceof Member) { +// completeMemberReferenceForDataUse(semanticElement, context, acceptor, "", "", " : access member"); + } else { +// completeMemberReferenceForDataUse(model, context, acceptor, "", "", " : access member"); + } +// if (model instanceof MemberReference) { +// DataType dataType = ((MemberReference)model).getMember().getDataType(); +// if (dataType instanceof StructuredDataType) { +// for (Member m : ((StructuredDataType) dataType).allMembers()) { +// acceptor.accept(createCompletionProposal("."+m.getName(), new StyledString(m.getName()), getImage(m), 100000, "", context)); +// } +// } +// } + + //super: empty + if (superRule) + super.complete_MemberReference(model, ruleCall, context, acceptor); + } + + @Override + public void completeMemberReference_Member(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + // TODO Auto-generated method stub +// System.out.println(context.getCurrentNode().getText()); +// System.out.println(context.getLastCompleteNode().getText()); + if (model instanceof DataElementUse) { + EList reduction = ((DataElementUse)model).getReduction(); + if (reduction.isEmpty()) { + completeMemberReferenceForDataUse(model, context, acceptor, "(", " = ?)", " : assign to member"); + return; + } else { +// ((DataElementUse)model).resolveDataType(); + if (reduction.getLast().getMember() == null && reduction.size()>1) { + DataType dataType = reduction.get(reduction.size()-2).getMember().getDataType(); + completeMemberReferenceForDataUse(dataType, context, acceptor, "", "", " : access member"); + } else { + completeMemberReferenceForDataUse(model, context, acceptor, "", "", " : access member"); + } + return; + } + } + //super: lookupCrossReference + if (superReference) + super.completeMemberReference_Member(model, assignment, context, acceptor); + } + + + private void completeMemberReferenceForDataUse(EObject model, ContentAssistContext context, ICompletionProposalAcceptor acceptor, String prefix, String suffix, String description) { + if (model instanceof CastDataUse) { + DataType dataType = ((CastDataUse) model).getDataType(); + //?TODO: why dpes this error out + if (dataType instanceof StructuredDataType) { + for (Member m : ((StructuredDataType) dataType).allMembers()) { + acceptor.accept(createCompletionProposal(m.getName()+suffix, new StyledString(prefix+m.getName()+suffix).append(description, StyledString.DECORATIONS_STYLER), getImage(m), 1000, "", context)); + } + } + } else if (model instanceof DataElementUse) { + //TODO: add suffix? e.g. = + NamedElement dataElement = ((DataElementUse) model).getDataElement(); + EList reduction = ((DataElementUse)model).getReduction(); + List assigned = ((DataElementUse) model).getArgument().stream() + .map(ParameterBinding::getParameter) + .toList(); + + //TODO: a bit of a hack.. this belongs elsewhere -> affects the whole chain, should be applied selectively +// System.out.println(model); +// System.out.println(context.getPreviousModel()); +// +// if (reduction.size() > 1) { +// dataElement = reduction.get(reduction.size()-2).getMember().getDataType(); +// } + if (dataElement instanceof StructuredDataType) { + acceptMembers(context, acceptor, prefix, suffix, description, assigned, (StructuredDataType) dataElement); + } else if (dataElement instanceof StructuredDataInstance) { + acceptMembers(context, acceptor, prefix, suffix, description, assigned, (StructuredDataType) ((StructuredDataInstance)dataElement).getDataType()); + } else if (dataElement instanceof FormalParameter) { + DataType dataType = ((FormalParameter) dataElement).getDataType(); + if (dataType instanceof StructuredDataType) { + acceptMembers(context, acceptor, prefix, suffix, description, assigned, (StructuredDataType) dataType); + } + } else if (dataElement instanceof Function) { + DataType dataType = ((Function) dataElement).getReturnType(); + if (dataType instanceof StructuredDataType) { + acceptMembers(context, acceptor, prefix, suffix, description, assigned, (StructuredDataType) dataType); + } + } + } else if (model instanceof StructuredDataType) { + //TODO: add already assigned + acceptMembers(context, acceptor, prefix, suffix, description, Collections.emptyList(), (StructuredDataType) model); + + } else if (model instanceof StructuredDataInstance) { + StructuredDataInstance instance = (StructuredDataInstance) model; + //get assigned members of instance + List assigned = instance.getMemberAssignment().stream() + .map(MemberAssignment::getMember) + .map(e -> (Parameter) e) + .toList(); + + acceptMembers(context, acceptor, prefix, suffix, description, assigned, (StructuredDataType) instance.getDataType()); + } else if (model instanceof MemberReference) { + DataType dataType = ((MemberReference) model).getMember().getDataType(); + //TODO: add already assigned + if (dataType instanceof StructuredDataType) { + acceptMembers(context, acceptor, prefix, suffix, description, Collections.emptyList(), (StructuredDataType) dataType); + } + } else if (model instanceof Member) { + DataType dataType = ((Member) model).getDataType(); + //TODO: add already assigned + if (dataType instanceof StructuredDataType) { + acceptMembers(context, acceptor, prefix, suffix, description, Collections.emptyList(), (StructuredDataType) dataType); + } + } + } + + private void acceptMembers(ContentAssistContext context, ICompletionProposalAcceptor acceptor, String prefix, + String suffix, String description, List assigned, StructuredDataType type) { + for (Member m : type.allMembers()) { + if (!assigned.contains(m)) { + acceptor.accept(createCompletionProposal(prefix+m.getName()+suffix, new StyledString(prefix+m.getName()+suffix).append(description, StyledString.DECORATIONS_STYLER), getImage(m), 100000, "", context)); + } + } + } + + @Override + public void completeCollectionItemFragment_Item(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model instanceof DataElementUse) { + NamedElement dataElement = ((DataElementUse) model).getDataElement(); + if (dataElement instanceof CollectionDataType) { + DataType itemType = ((CollectionDataType) dataElement).getItemType(); + completeAssignment(model, context, acceptor, itemType); + return; //? + } + } + //super completeRuleCall + if (superContainment) + super.completeCollectionItemFragment_Item(model, assignment, context, acceptor); + } + @Override public void complete_FunctionCall(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { acceptor.accept(createCompletionProposal("instance returned from ",context)); - super.complete_FunctionCall(model, ruleCall, context, acceptor); + //super empty + if (superRule) + super.complete_FunctionCall(model, ruleCall, context, acceptor); } @Override public void completePredefinedFunctionCallBinary_Function(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { // TODO: handle here or in scope provider - exclude incorrect proposals - super.completePredefinedFunctionCallBinary_Function(model, assignment, context, acceptor); + if (model instanceof ParameterBinding || model instanceof MemberReference) { + return; + } + //super lookupCrossReference + if (superReference) + super.completePredefinedFunctionCallBinary_Function(model, assignment, context, acceptor); } @Override public void completePredefinedFunctionCallBinary_ActualParameters(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { // TODO: refine? - super.completePredefinedFunctionCallBinary_ActualParameters(model, assignment, context, acceptor); + //super: completeRuleCall + if (superContainment) + super.completePredefinedFunctionCallBinary_ActualParameters(model, assignment, context, acceptor); } @Override public void complete_PredefinedFunctionCallBinary(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { // TODO: refine? - super.complete_PredefinedFunctionCallBinary(model, ruleCall, context, acceptor); + if (model instanceof ParameterBinding || model instanceof MemberReference) { + return; + } + //TODO: what and why? + //super.complete_PredefinedIdentifierBinary(model, ruleCall, context, acceptor); + //super: empty + if (superRule) + super.complete_PredefinedFunctionCallBinary(model, ruleCall, context, acceptor); + } + + @Override + public void complete_PredefinedFunctionCall(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding || model instanceof MemberReference) { + return; + } + //super: empty + if (superRule) + super.complete_PredefinedFunctionCall(model, ruleCall, context, acceptor);} + + @Override + public void complete_PredefinedIdentifierBinary(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + // TODO Auto-generated method stub + if (model instanceof ParameterBinding || model instanceof MemberReference) { + return; + } + if (model instanceof SimpleDataType) { + return; + } + //super: empty + if (superRule) + super.complete_PredefinedIdentifierBinary(model, ruleCall, context, acceptor); } + @Override public void complete_TargetMessage(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - super.complete_TargetMessage(model, ruleCall, context, acceptor); + //super: empty + if (superRule) + super.complete_TargetMessage(model, ruleCall, context, acceptor); } @Override public void completeMessage_Target(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - super.completeMessage_Target(model, assignment, context, acceptor); + //super: completeRuleCall + if (superContainment) + super.completeMessage_Target(model, assignment, context, acceptor); } @Override public void completeTargetMessage_TargetGate(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - super.completeTargetMessage_TargetGate(model, assignment, context, acceptor); + + //super lookupCrossReference + if (superReference) //TODO: this should be exempt? + super.completeTargetMessage_TargetGate(model, assignment, context, acceptor); + EList connection = ((Message) model).getParentTestDescription().getTestConfiguration().getConnection(); for (Connection c : connection) { //TODO: simplify, filter? move upstream?, also for procedure target? @@ -93,7 +714,110 @@ public class TDLtxProposalProvider extends AbstractTDLtxProposalProvider { public void complete_TimeConstraintFragment(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { acceptor.accept(createCompletionProposal("{ }",context)); - super.complete_TimeConstraintFragment(model, ruleCall, context, acceptor); + //super: empty + if (superRule) + super.complete_TimeConstraintFragment(model, ruleCall, context, acceptor); + } + + public void completeVariableUse_ComponentInstance(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding || model instanceof MemberReference) { + return; + } + //super lookupCrossReference + if (superReference) //TODO: this should be exempt? + super.completeVariableUse_ComponentInstance(model, assignment, context, acceptor); + } + + public void completePredefinedFunctionCallSize_Function(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding || model instanceof MemberAssignment || model instanceof MemberReference) { +// complete_ParameterBinding(model, ruleCall, context, acceptor); + return; + } + //super lookupCrossReference + if (superReference) + super.completePredefinedFunctionCallSize_Function(model, assignment, context, acceptor); + } + + public void completePredefinedFunctionCallNot_Function(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding || model instanceof MemberAssignment || model instanceof MemberReference) { +// complete_ParameterBinding(model, ruleCall, context, acceptor); + return; + } + //super lookupCrossReference + if (superReference) + super.completePredefinedFunctionCallNot_Function(model, assignment, context, acceptor); + } + + public void completePredefinedFunctionCallMinus_Function(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding || model instanceof MemberAssignment || model instanceof MemberReference) { +// complete_ParameterBinding(model, ruleCall, context, acceptor); + return; + } + //super lookupCrossReference + if (superReference) + super.completePredefinedFunctionCallMinus_Function(model, assignment, context, acceptor); + } + + + public void completeDataElementUse_DataElement(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding || model instanceof MemberAssignment || model instanceof MemberReference) { +// complete_ParameterBinding(model, ruleCall, context, acceptor); + return; + } + //super lookupCrossReference + if (superReference) + super.completeDataElementUse_DataElement(model, assignment, context, acceptor); + } + public void complete_DataElementUse(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + if (model instanceof ParameterBinding || model instanceof MemberAssignment || model instanceof MemberReference) { +// complete_ParameterBinding(model, ruleCall, context, acceptor); + return; + } + + //super: empty + if (superRule) + super.complete_DataElementUse(model, ruleCall, context, acceptor); + + } + + @Override + public void complete_Argument(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + //super: empty + if (superRule) + super.complete_Argument(model, ruleCall, context, acceptor); + } + + @Override + public void completeMessage_Argument(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model instanceof Message) { + var m = ((Message) model); + var types = m.getSourceGate().getGate().getType().allDataTypes(); + for (var type : types) { + completeAssignment(model, context, acceptor, type); + } + } + + //super: completeRuleCall + if (superContainment) + super.completeMessage_Argument(model, assignment, context, acceptor); } -} + @Override + public void completeReceiveMessage_Argument(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + if (model instanceof Message) { + var m = ((Message) model); + var types = m.getSourceGate().getGate().getType().allDataTypes(); + for (var type : types) { + completeAssignment(model, context, acceptor, type); + } + } + + //super: completeRuleCall + if (superContainment) + super.completeReceiveMessage_Argument(model, assignment, context, acceptor); + } + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxHighlightingCalculator.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxHighlightingCalculator.java new file mode 100644 index 0000000000000000000000000000000000000000..679696503c27d3548d40d2c88555e089f70035f1 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxHighlightingCalculator.java @@ -0,0 +1,188 @@ +package org.etsi.mts.tdl.ui.highlighting; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.xtext.nodemodel.ILeafNode; +import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightedPositionAcceptor; +import org.eclipse.xtext.ui.editor.syntaxcoloring.ISemanticHighlightingCalculator; +import org.etsi.mts.tdl.ActionBehaviour; +import org.etsi.mts.tdl.ActionReference; +import org.etsi.mts.tdl.AnyValue; +import org.etsi.mts.tdl.Assertion; +import org.etsi.mts.tdl.Assignment; +import org.etsi.mts.tdl.ComponentInstance; +import org.etsi.mts.tdl.ComponentType; +import org.etsi.mts.tdl.DataInstance; +import org.etsi.mts.tdl.DataInstanceUse; +import org.etsi.mts.tdl.DataType; +import org.etsi.mts.tdl.Function; +import org.etsi.mts.tdl.GateInstance; +import org.etsi.mts.tdl.GateReference; +import org.etsi.mts.tdl.GateType; +import org.etsi.mts.tdl.InlineAction; +import org.etsi.mts.tdl.Interaction; +import org.etsi.mts.tdl.Member; +import org.etsi.mts.tdl.Parameter; +import org.etsi.mts.tdl.Quiescence; +import org.etsi.mts.tdl.Target; +import org.etsi.mts.tdl.tdlPackage; +import org.etsi.mts.tdl.structuredobjectives.Event; +import org.etsi.mts.tdl.structuredobjectives.EventReference; +import org.etsi.mts.tdl.structuredobjectives.StructuredObjectivesPackage; +import org.etsi.mts.tdl.structuredobjectives.impl.StructuredTestObjectiveImpl; +import org.etsi.mts.tdl.TestConfiguration; +import org.etsi.mts.tdl.TestDescription; +import org.etsi.mts.tdl.TimerOperation; +import org.etsi.mts.tdl.VariableUse; +import org.etsi.mts.tdl.VerdictAssignment; +import org.etsi.mts.tdl.Wait; + +public class TDLtxHighlightingCalculator implements ISemanticHighlightingCalculator { + + +// @Override + public void provideHighlightingFor( XtextResource resource, IHighlightedPositionAcceptor acceptor ) { + if( resource == null ) { + return; + } + + Iterator iter = EcoreUtil.getAllContents(resource, true); + while(iter.hasNext()) { + EObject current = iter.next(); + if (current instanceof Event) { + INode name = getFirstFeatureNode( current, StructuredObjectivesPackage.eINSTANCE.getEvent().getEStructuralFeature("name")); + highlightNode( name, TDLtxHighlightingConfiguration.KEYWORD_ID, acceptor); + } else if (current instanceof EventReference) { + INode node = getFirstFeatureNode( current, StructuredObjectivesPackage.eINSTANCE.getEventReference_Event()); + highlightNode( node, TDLtxHighlightingConfiguration.KEYWORD_ID, acceptor); + +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getGateInstance_Type()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof GateInstance) { +// INode name = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getGateInstance().getEStructuralFeature("name")); +// highlightNode( name, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getGateInstance_Type()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof GateType) { +// INode name = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getGateType().getEStructuralFeature("name")); +// highlightNode( name, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// List nodes = getAllFeatureNodes( current, tdlPackage.eINSTANCE.getGateType_DataType()); +// for (INode node : nodes) { +// highlightNode( node, TDLtxHighlightingConfiguration.DATATYPE_LAYOUT, acceptor); +// } +// } else if (current instanceof GateReference) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getGateReference_Component()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// INode gate = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getGateReference_Gate()); +// highlightNode( gate, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof TestConfiguration) { +// INode name = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getTestConfiguration().getEStructuralFeature("name")); +// highlightNode( name, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getTestDescription_TestConfiguration()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof ComponentInstance) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getComponentInstance().getEStructuralFeature("name")); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +//// INode gate = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getComponentInstance_Gate()); +//// highlightNode( gate, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// INode type = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getComponentInstance_Type()); +// highlightNode( type, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof ComponentType) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getComponentType().getEStructuralFeature("name")); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof DataInstance) { +// INode name = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getDataInstance().getEStructuralFeature("name")); +// highlightNode( name, TDLtxHighlightingConfiguration.DATA_LAYOUT, acceptor); +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getDataInstance_DataType()); +// highlightNode( node, TDLtxHighlightingConfiguration.DATATYPE_LAYOUT, acceptor); +// } else if (current instanceof DataType) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getDataType().getEStructuralFeature("name")); +// highlightNode( node, TDLtxHighlightingConfiguration.DATATYPE_LAYOUT, acceptor); +// } else if (current instanceof Parameter) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getParameter_DataType()); +// highlightNode( node, TDLtxHighlightingConfiguration.DATATYPE_LAYOUT, acceptor); +// } else if (current instanceof Function) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getFunction_ReturnType()); +// highlightNode( node, TDLtxHighlightingConfiguration.DATATYPE_LAYOUT, acceptor); +// } else if (current instanceof Function) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getFunction_ReturnType()); +// highlightNode( node, TDLtxHighlightingConfiguration.DATATYPE_LAYOUT, acceptor); +// } else if (current instanceof DataInstanceUse) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getDataInstanceUse_DataInstance()); +// highlightNode( node, TDLtxHighlightingConfiguration.DATA_LAYOUT, acceptor); +// } else if (current instanceof AnyValue) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getAnyValue_DataType()); +// highlightNode( node, TDLtxHighlightingConfiguration.DATATYPE_LAYOUT, acceptor); +// } else if (current instanceof VerdictAssignment) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getVerdictAssignment_Verdict()); +// highlightNode( node, TDLtxHighlightingConfiguration.BEHAVIOUR_LAYOUT, acceptor); +// } else if (current instanceof Assertion) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getAssertion_Otherwise()); +// highlightNode( node, TDLtxHighlightingConfiguration.BEHAVIOUR_LAYOUT, acceptor); +// } else if (current instanceof Interaction) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getInteraction_SourceGate()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof Target) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getTarget_TargetGate()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof Quiescence) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getQuiescence_GateReference()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// INode component = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getTimeOperation_ComponentInstance()); +// highlightNode( component, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof Wait) { +// INode component = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getTimeOperation_ComponentInstance()); +// highlightNode( component, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof VariableUse) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getVariableUse_ComponentInstance()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof ActionBehaviour) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getActionBehaviour_ComponentInstance()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof TimerOperation) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getTimerOperation_ComponentInstance()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); +// } else if (current instanceof TestDescription) { +// INode node = getFirstFeatureNode( current, tdlPackage.eINSTANCE.getTestDescription_TestConfiguration()); +// highlightNode( node, TDLtxHighlightingConfiguration.CONFIGURATION_LAYOUT, acceptor); + } + + } + } + + private void highlightNode( INode node, String id, IHighlightedPositionAcceptor acceptor ) { + if( node == null ) + return; + if( node instanceof ILeafNode ) { + acceptor.addPosition( node.getOffset(), node.getLength(), id ); + } else { + for( ILeafNode leaf : node.getLeafNodes() ) { + if( !leaf.isHidden() ) { + acceptor.addPosition( leaf.getOffset(), leaf.getLength(), id ); + } + } + } + } + + public INode getFirstFeatureNode( EObject semantic, EStructuralFeature feature ) { + if( feature == null ) + return NodeModelUtils.findActualNodeFor( semantic ); + List nodes = NodeModelUtils.findNodesForFeature( semantic, feature ); + if( !nodes.isEmpty() ) + return nodes.get( 0 ); + return null; + } + public List getAllFeatureNodes( EObject semantic, EStructuralFeature feature ) { + List nodes = NodeModelUtils.findNodesForFeature( semantic, feature ); + if( !nodes.isEmpty() ) + return nodes; + return null; + } + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxHighlightingConfiguration.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxHighlightingConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..ff73b5bd9f553841f9fde91f8152588c818d3e64 --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxHighlightingConfiguration.java @@ -0,0 +1,62 @@ +package org.etsi.mts.tdl.ui.highlighting; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultHighlightingConfiguration; +import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfigurationAcceptor; +import org.eclipse.xtext.ui.editor.utils.TextStyle; + +public class TDLtxHighlightingConfiguration extends DefaultHighlightingConfiguration { + + public static final String EXTRA_KEYWORD_LAYOUT = "extra_keyword"; + private static final RGB EXTRA_KEYWORD_COLOUR = new RGB(150, 100, 100); + public static final String BEHAVIOUR_LAYOUT = "behaviour"; + private static final RGB BEHAVIOUR_COLOUR = new RGB(150, 140, 120); + public static final String CONFIGURATION_LAYOUT = "configuration"; + private static final RGB CONFIGURATION_COLOUR = new RGB(50, 40, 120); + public static final String DATA_LAYOUT = "data"; + private static final RGB DATA_COLOUR = new RGB(110, 140, 150); + public static final String DATATYPE_LAYOUT = "datatype"; + private static final RGB DATATYPE_COLOUR = new RGB(150, 40, 150); + + @Override + public void configure(IHighlightingConfigurationAcceptor acceptor) { + super.configure(acceptor); + acceptor.acceptDefaultHighlighting(EXTRA_KEYWORD_LAYOUT, "Additional Keywords", extraKeywordLayoutTextStyle()); + acceptor.acceptDefaultHighlighting(BEHAVIOUR_LAYOUT, "Behaviour", behaviourLayoutTextStyle()); + acceptor.acceptDefaultHighlighting(CONFIGURATION_LAYOUT, "Configuration", configurationLayoutTextStyle()); + acceptor.acceptDefaultHighlighting(DATA_LAYOUT, "Data", dataLayoutTextStyle()); + acceptor.acceptDefaultHighlighting(DATATYPE_LAYOUT, "Data Type", dataTypeLayoutTextStyle()); + } + + public TextStyle behaviourLayoutTextStyle() { + TextStyle textStyle = new TextStyle(); + textStyle.setStyle(SWT.BOLD); + textStyle.setColor(BEHAVIOUR_COLOUR); + return textStyle; + } + public TextStyle extraKeywordLayoutTextStyle() { + TextStyle textStyle = new TextStyle(); + textStyle.setStyle(SWT.BOLD); + textStyle.setColor(EXTRA_KEYWORD_COLOUR); + return textStyle; + } + public TextStyle configurationLayoutTextStyle() { + TextStyle textStyle = new TextStyle(); + textStyle.setStyle(SWT.BOLD); + textStyle.setColor(CONFIGURATION_COLOUR); + return textStyle; + } + public TextStyle dataLayoutTextStyle() { + TextStyle textStyle = new TextStyle(); + textStyle.setStyle(SWT.ITALIC); + textStyle.setColor(DATA_COLOUR); + return textStyle; + } + public TextStyle dataTypeLayoutTextStyle() { + TextStyle textStyle = new TextStyle(); + textStyle.setStyle(SWT.ITALIC | SWT.UNDERLINE_SINGLE); + textStyle.setColor(DATATYPE_COLOUR); + return textStyle; + } + +} \ No newline at end of file diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxTokenToAttributeIdMapper.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxTokenToAttributeIdMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..69dd68aa3d1910090960e844571f98736187ad9f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/highlighting/TDLtxTokenToAttributeIdMapper.java @@ -0,0 +1,46 @@ +package org.etsi.mts.tdl.ui.highlighting; +import java.util.HashSet; + +import org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultAntlrTokenToAttributeIdMapper; + +public class TDLtxTokenToAttributeIdMapper extends DefaultAntlrTokenToAttributeIdMapper { + + private HashSet extraKeywords = new HashSet(); + private HashSet configurationKeywords = new HashSet(); + + public TDLtxTokenToAttributeIdMapper() { + extraKeywords.add("'calls'"); + extraKeywords.add("'receives'"); + extraKeywords.add("'sends'"); + extraKeywords.add("'triggers'"); + extraKeywords.add("'times'"); + extraKeywords.add("'out'"); + extraKeywords.add("'starts'"); + extraKeywords.add("'stops'"); + extraKeywords.add("'waits'"); + extraKeywords.add("'returns'"); +// configurationKeywords.add("'creates'"); +// configurationKeywords.add("'uses'"); + + // for (Color color : Color.values()) { + // System.out.println(color.getLiteral() + "::" + color.getName()); + // layoutKeywords.add("'" + color.getName().toLowerCase() + "'"); + // } + } + + @Override + protected String calculateId(String tokenName, int tokenType) { + if (extraKeywords.contains(tokenName)) { + return TDLtxHighlightingConfiguration.KEYWORD_ID; + } + if (configurationKeywords.contains(tokenName)) { + return TDLtxHighlightingConfiguration.KEYWORD_ID; + } + return super.calculateId(tokenName, tokenType); + } + + public String getId(int tokenType) { + return getMappedValue(tokenType); + } + +} diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/hover/TDLtxHoverProvider.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/hover/TDLtxHoverProvider.java index 2e90e276e23a966209e810b14fe447a71ba3922a..a12ca7c015c6d359e705c38df2ece2d7a1bb75fe 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/hover/TDLtxHoverProvider.java +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/hover/TDLtxHoverProvider.java @@ -1,20 +1,49 @@ package org.etsi.mts.tdl.ui.hover; import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature.Setting; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.xtext.EcoreUtil2; import org.eclipse.xtext.ui.editor.hover.html.DefaultEObjectHoverProvider; +import org.etsi.mts.tdl.AnyValue; +import org.etsi.mts.tdl.AnyValueOrOmit; +import org.etsi.mts.tdl.CastDataUse; +import org.etsi.mts.tdl.CollectionDataInstance; +import org.etsi.mts.tdl.CollectionDataType; +import org.etsi.mts.tdl.DataElementUse; +import org.etsi.mts.tdl.DataUse; +import org.etsi.mts.tdl.Element; +import org.etsi.mts.tdl.Function; +import org.etsi.mts.tdl.LiteralValueUse; +import org.etsi.mts.tdl.Member; +import org.etsi.mts.tdl.MemberAssignment; +import org.etsi.mts.tdl.MemberReference; +import org.etsi.mts.tdl.Message; +import org.etsi.mts.tdl.NamedElement; +import org.etsi.mts.tdl.PackageableElement; +import org.etsi.mts.tdl.Parameter; +import org.etsi.mts.tdl.ParameterBinding; +import org.etsi.mts.tdl.SimpleDataInstance; +import org.etsi.mts.tdl.StructuredDataInstance; import org.etsi.mts.tdl.StructuredDataType; import org.etsi.mts.tdl.TestDescription; import org.etsi.mts.tdl.TestObjective; +import org.etsi.mts.tdl.Variable; public class TDLtxHoverProvider extends DefaultEObjectHoverProvider { protected String getHoverInfoAsHtml(EObject o) { String html = super.getHoverInfoAsHtml(o); + if (o instanceof NamedElement) { + html = ""+o.eClass().getName()+" : "+((NamedElement) o).getName()+""; + } if (o instanceof TestObjective) { //TODO: search within resource set? //TODO: basic PoC, elaborate further, e.g. links, other info @@ -23,18 +52,318 @@ public class TDLtxHoverProvider extends DefaultEObjectHoverProvider { for (Setting f : found) { f.getEObject(); } - html+="

Referenced in:
  • "+targets+"
"; + html+="

Description:
  • "+((TestObjective) o).getDescription()+"
"; + html+="References:
  • "+((TestObjective) o).getObjectiveURI().stream().collect(Collectors.joining("
  • "))+"
"; + html+="Referenced in:
  • "+targets+"

"; + } + if (o instanceof TestDescription) { + if (!((TestDescription) o).getTestObjective().isEmpty()) { + html+="

Objectives:
  • "+((TestDescription) o).getTestObjective().stream().map(e->e.getName()+": "+e.getDescription()).collect(Collectors.joining("
  • "))+"
"; + } } if (o instanceof StructuredDataType) { - String members = ((StructuredDataType) o).allMembers().stream().map(e -> e.getName() + " : "+e.getDataType().getName()).collect(Collectors.joining("
  • ")); - html+="

    Members:
    • "+members+"
    "; + String members = getListOfMembers((StructuredDataType) o); + html+="

    Members: "+members+"
    "; } + if (o instanceof StructuredDataInstance) { + StructuredDataInstance instance = (StructuredDataInstance) o; + html+="

    Type: "+instance.getDataType().getName()+""; + String members = getListOfMembers((StructuredDataType) instance.getDataType()); + html+="

    Members: "+members+""; + //TODO: merge assignments above? + String unassigned = getListOfUnassignedMembers((StructuredDataType) instance.getDataType(), instance.getMemberAssignment()); + if (!unassigned.equals("
    ")) { + html+="Unassigned Members: "+unassigned+""; + } + String contents = ""; + contents = getNestedListOfMembersWithValues(instance); + html+="Contents:
    "+contents+"
    "; + + } + if (o instanceof Variable) { + html+="

    Type: "+((Variable) o).getDataType().getName()+""; + } + if (o instanceof Parameter) { + html+="

    Type: "+((Parameter) o).getDataType().getName()+""; + if (((Parameter) o).getDataType() instanceof StructuredDataType) { + String members = getListOfMembers((StructuredDataType) ((Parameter) o).getDataType()); + html+="

    Members: "+members+"
    "; + //not really possible to determine +// String unbound = getListOfUnboundParameters(((StructuredDataType) ((Parameter) o).getDataType()), o); +// html+="

    Unbound Parameters: "+unbound+""; + } + } + //TODO: data use -> partially done in data instance + if (o instanceof DataUse) { + html+="DATA"; + } + if (o instanceof Message) { + Message m = ((Message) o); + html="Message: "+m.getSourceGate().getComponent().getName() + +" --> "+m.getTarget().get(0).getTargetGate().getComponent().getName()+"
    "; + String contents = ""; + contents = getNestedListOfMembersWithValues(m.getArgument()); + html+="Contents:
    "+contents+"
    "; + } return html; } + //TODO: move to label providers? + private String getListOfMembers(StructuredDataType o) { + String members = o.allMembers().stream() + .map(e -> e.getName() + " : "+e.getDataType().getName() + (e.isIsOptional() ? " (optional)" : "")) + .collect(Collectors.joining("
  • ")); + return "
    • "+members+"
    "; + } + + private String getNestedListOfMembersWithValues(StructuredDataInstance i) { + StructuredDataType o = (StructuredDataType) i.getDataType(); + Map assigned = i.getMemberAssignment().stream().collect(Collectors.toMap(MemberAssignment::getMember, MemberAssignment::getMemberSpec)); + String members = ""; + for (var m : o.allMembers()) { + members += "
  • "; + members += m.getName(); + if (assigned.containsKey(m)) { + members += " = " + getNestedListOfMembersWithValues(assigned.get(m)); + } else { + //TODO: unassigned treatment + members += " : ("+m.getDataType().getName()+")"; + } + //TODO: optional + members += "
  • "; + } + +// String members = o.allMembers().stream() +// .map(e -> e.getName() + " : "+e.getDataType().getName() + (e.isIsOptional() ? " (optional)" : "") +// + ((e.getDataType() instanceof StructuredDataType) ? +// "
    • "+getNestedListOfMembersWithValues(e.get)+"
    " : "") +// ) +// .collect(Collectors.joining("
  • ")); + return "
      "+members+"
    "; + } + + //TODO: split + private String getNestedListOfMembersWithValues(DataUse u) { + String content = ""; + //TODO: resolve reduction value + if (u instanceof DataElementUse) { + NamedElement dataElement = ((DataElementUse) u).getDataElement(); + if (dataElement!=null) { + if (dataElement instanceof StructuredDataInstance) { + //TODO: extract + Map assigned = getAssigned((StructuredDataInstance) dataElement); + Map bound = getBound(u); + StructuredDataType o = (StructuredDataType) ((StructuredDataInstance) dataElement).getDataType(); + + if (!u.getReduction().isEmpty()) { + content += getReduction(u.getReduction(), assigned); + } else { + content += "
      " + getMembersWithOverrides(assigned, bound, o) + "
    "; + } + //content += " = " + getNestedListOfMembersWithValues((StructuredDataInstance) dataElement); + } else if (dataElement instanceof StructuredDataType) { + content += getArguments(u); + } else if (dataElement instanceof CollectionDataInstance) { + EList itemList = ((CollectionDataInstance) dataElement).getItem(); + String items = ""; + for (var iu : itemList) { + items += getNestedListOfMembersWithValues(iu); + } + content += "
  • "+items+"
  • "; + } else if (dataElement instanceof CollectionDataType) { + EList itemList = ((DataElementUse) u).getItem(); + String items = ""; + for (var iu : itemList) { + items += "
  • ("+((CollectionDataType)dataElement).getItemType().getName()+")"+getNestedListOfMembersWithValues(iu)+"
  • "; + } + content += "
      "+items+"
    "; + } else if (dataElement instanceof SimpleDataInstance) { + content += ""+dataElement.getName()+""; + } else if (dataElement instanceof Parameter) { + content += ""+dataElement.getName()+""; + } else if (dataElement instanceof Function) { + content += "->"+dataElement.getName()+""; + } + } else if (!u.getArgument().isEmpty()) { + //structured + content += getArguments(u); +// Map assigned = Collections.emptyMap(); +// Map bound = getBound(u); +// content += "
      "+getMembersWithOverrides(assigned, bound, (StructuredDataType) u.resolveDataType())+"
    "; + } else if (!((DataElementUse) u).getItem().isEmpty()) { + //collection + EList itemList = ((DataElementUse) u).getItem(); + String items = ""; + for (var iu : itemList) { + items += "
  • ("+(u.resolveDataType().getName())+")"+getNestedListOfMembersWithValues(iu)+"
  • "; + } + content += "
      "+items+"
    "; + } else { + content += getArguments(u); + } + //TODO: handle items + //TODO: handle reduction + } else if (u instanceof LiteralValueUse) { + content += getLiteralValue((LiteralValueUse)u); + } else if (u instanceof AnyValue) { + content += "" + "?"; + } else if (u instanceof AnyValueOrOmit) { + content += "" + "*"; + } else if (u instanceof CastDataUse) { + Map assigned = getAssignedOrBoundWithReduction(u); + if (assigned.containsKey(null)) { + content += getNestedListOfMembersWithValues(assigned.get(null)); + } else { + content += "
      "; + for (var b : assigned.keySet()) { + content += "
    • "; + content += b.getName(); + content += " = " + getNestedListOfMembersWithValues(assigned.get(b)); + content += "
    • "; + } + content += "
    "; + } +// content += getCast((CastDataUse)u); + } + //TODO: others? + return content; + } + + private Map getBound(DataUse u) { + Map bound = u.getArgument() + .stream() + .filter(e->e.getReduction().isEmpty()) + .collect(Collectors.toMap(ParameterBinding::getParameter, ParameterBinding::getDataUse)); + return bound; + } + + private Map getAssigned(StructuredDataInstance instance) { + Map assigned = instance.getMemberAssignment() + .stream().collect(Collectors.toMap(MemberAssignment::getMember, MemberAssignment::getMemberSpec)); + return assigned; + } + + private String getReduction(EList reduction, Map assigned) { + String content = ""; + DataUse ru = null; + for (var r : reduction) { + //TODO: handle indices? + if (r.getMember() != null) { + if (assigned.containsKey(r.getMember())) { + ru = assigned.get(r.getMember()); + assigned = getAssignedOrBoundWithReduction(ru); + } + } + } + content += getNestedListOfMembersWithValues(ru); + return content; + } + + private Map getAssignedOrBound(DataUse u) { + Map assigned = Collections.emptyMap(); + if (u instanceof DataElementUse) { + if (((DataElementUse) u).getDataElement() instanceof StructuredDataInstance) { + assigned = getAssigned((StructuredDataInstance) ((DataElementUse)u).getDataElement()); + } else if (((DataElementUse) u).getDataElement() instanceof StructuredDataType) { + assigned = getBound(u); + } else if (((DataElementUse) u).getDataElement() instanceof CollectionDataType) { + //TODO: handle? + } + //TODO: also simple data instances, enums? + } else if (u instanceof CastDataUse) { + assigned = getAssignedOrBoundWithReduction(((CastDataUse) u).getDataUse()); + } else if (u instanceof LiteralValueUse) { + assigned = Collections.singletonMap(null, u); + } else if (u instanceof AnyValue) { + assigned = Collections.singletonMap(null, u); + } else if (u instanceof AnyValueOrOmit) { + assigned = Collections.singletonMap(null, u); + } + return assigned; + } + + private Map getAssignedOrBoundWithReduction(DataUse u) { + Map assigned = getAssignedOrBound(u); + if (!u.getReduction().isEmpty()) { + DataUse ru = null; + for (var r : u.getReduction()) { + if (r.getMember() != null) { + if (assigned.containsKey(r.getMember())) { + ru = assigned.get(r.getMember()); + assigned = getAssignedOrBound(ru); + //TODO: handle cast? + } + } + } + } + return assigned; + } + + private String getLiteralValue(LiteralValueUse u) { + String content = ""; + if (u.getValue() != null) { + content += "\""+u.getValue()+"\""; + } else if (u.getIntValue() != null) { + content += u.getIntValue(); + } else if (u.getBoolValue() != null) { + content += u.getBoolValue(); + } + return content; + } + + private String getMembersWithOverrides(Map assigned, Map bound, StructuredDataType o) { + String members = ""; + for (var m : o.allMembers()) { + members += "
  • "; + members += m.getName(); + if (bound.containsKey(m)) { + members += " = " + getNestedListOfMembersWithValues(bound.get(m)); + } else if (assigned.containsKey(m)) { + members += " = " + getNestedListOfMembersWithValues(assigned.get(m)); + } else { + //TODO: unassigned treatment + members += " : ("+m.getDataType().getName()+")"; + } + //TODO: optional + members += "
  • "; + } + return members; + } + + private String getArguments(DataUse u) { + String content = ""; + content += "
      "; + for (var b : u.getArgument()) { + content += "
    • "; + content += b.getParameter().getName(); + content += " = " + getNestedListOfMembersWithValues(b.getDataUse()); + content += "
    • "; + } + content += "
    "; + return content; + } + + private String getListOfUnassignedMembers(StructuredDataType o, List m) { + List assigned = m.stream().map(e->e.getMember()).collect(Collectors.toList()); + String members = o.allMembers().stream() + .filter(e->!assigned.contains(e)) + .map(e -> e.getName() + " : "+e.getDataType().getName() + (e.isIsOptional() ? " (optional)" : "")) + .collect(Collectors.joining("
  • ")); + return "
    • "+members+"
    "; + } + + private String getListOfUnboundParameters(StructuredDataType o, List m) { + List assigned = m.stream().map(e->e.getParameter()).collect(Collectors.toList()); + String members = o.allMembers().stream() + .filter(e->!assigned.contains(e)) + .map(e -> e.getName() + " : "+e.getDataType().getName() + (e.isIsOptional() ? " (optional)" : "")) + .collect(Collectors.joining("
  • ")); + return "
    • "+members+"
    "; + } + + protected String getHoverInfoAsHtml(TestObjective o) { String html = super.getHoverInfoAsHtml(o); - System.out.println(html); return html; } diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/Messages.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/Messages.java index 05f84eac226b97aecd642d166452f003972f23cf..d5e3b32dbc291a4e9fa73ac79444f1393d749326 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/Messages.java +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/Messages.java @@ -22,6 +22,14 @@ public class Messages extends NLS { public static String TDLtxLibrary_Description; public static String TDLtxProjectBase_Label; public static String TDLtxProjectBase_Description; + public static String TDLtxProjectBaseTPD_Label; + public static String TDLtxProjectBaseTPD_Description; + public static String TDLtxProjectExecutable_Label; + public static String TDLtxProjectExecutable_Description; + public static String TDLtxFileWithStandardLibrary_Label; + public static String TDLtxFileWithStandardLibrary_Description; + public static String TDLtxFileWithTPD_Label; + public static String TDLtxFileWithTPD_Description; static { // initialize resource bundle diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxFileTemplateProvider.xtend b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxFileTemplateProvider.xtend index b2bc99e88e6f80ead8c97dca54590a128c5b0780..fef80749d19386b71e5b9bd25697e7f353e32128 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxFileTemplateProvider.xtend +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxFileTemplateProvider.xtend @@ -3,14 +3,12 @@ */ package org.etsi.mts.tdl.ui.wizard - import org.eclipse.xtext.ui.wizard.template.FileTemplate import org.eclipse.xtext.ui.wizard.template.IFileGenerator import org.eclipse.xtext.ui.wizard.template.IFileTemplateProvider -import org.etsi.mts.tdl.openapi2tdl.next.ConverterNext -import org.eclipse.core.runtime.preferences.InstanceScope -import org.eclipse.ui.preferences.ScopedPreferenceStore -import org.etsi.mts.tdl.ui.wizard.TemplateHelper.Libraries +import org.eclipse.xtext.ui.wizard.template.WorkspaceFileGenerator + +import static extension org.etsi.mts.tdl.ui.wizard.WizardHelper.* /** * Create a list with all file templates to be shown in the template new file wizard. @@ -21,83 +19,141 @@ class TDLtxFileTemplateProvider implements IFileTemplateProvider { override getFileTemplates() { #[ new TDLtxFile, - new TDLtxFileFromOpenAPI, - new TDLtxLibrary + new TDLtxFileWithStandardLibrary, + new TDLtxFileWithTPD + //TODO: add TD, Test, TO templates ] } } -@FileTemplate(label="TDLtx", icon="file_template.png", description="Create a new package for TDLtx.") + +@FileTemplate(label="TDL Textual", icon="file_template.png", description="Create a new textual file for TDL.") final class TDLtxFile { //TODO: make it more sensible - val packageName = text("Package Name:", "EmptyPackage", "The name of the package") - +// val packageName = text("Package Name:", "", "The name of the package") +// val packageName = name //TODO: reuse? + override generateFiles(IFileGenerator generator) { - generator.generate('''«folder»/«name».tdltx''', ''' - /* - * This is an example model - */ - Package «packageName» { - - } - ''') -// generator.generate('''«folder»/«packageName».tdltx''', TemplateContent.Example) + if (generator instanceof WorkspaceFileGenerator) { + generator.generate('''«folder»/«name».tdltx''', ''' + /* + * This is an example model + */ + Package «name» { + + } + ''') + } else { + generator.generate('''«folder»/«name».tdltx''', "") + } +// generator.generate('''«folder»/«packageName».tdltx''', TemplateContent.Examplde) } } -@FileTemplate(label="TDLtx Library", icon="file_template.png", description="Add library for TDL.") -final class TDLtxLibrary { - //TODO: make it more sensible - //TODO: name should not be asked for... - val name = text("Name:", "TDL") - val packageName = combo("Library:", #["TDL", "HTTP"], "The library to be added.") - var validated = false - override protected updateVariables() { - validated = true - super.updateVariables() - } +@FileTemplate(label="TDL Textual with Standard TDL Libraries", icon="file_template.png", description="Create a new textual file for TDL importing standard libraries for TDL.") +final class TDLtxFileWithStandardLibrary { + protected val libraries = group("Select libraries to import:") + protected val includeTDL = check("TDL Standard Library", true, "Include TDL Standard Library (recommended)", libraries) + protected val includeHTTP = check("HTTP Protocol Library", true, "Include HTTP Protocol Library", libraries) + protected def String addLibraries(IFileGenerator generator) { + var imports = "" + if (includeTDL.value) { + generator.addLibraries("TDL", folder) + imports += "Import all from TDL\n" + } + if (includeHTTP.value) { + generator.addLibraries("HTTP", folder) + imports += "Import all from HTTP\n" + } + return imports + } + //TODO: reuse? override generateFiles(IFileGenerator generator) { //TODO: use enum values? - if (validated) { - generator.generate('''«folder»/«name».tdltx''', TemplateHelper.getLibrary(packageName.value)) - } + if (generator instanceof WorkspaceFileGenerator) { + var imports = addLibraries(generator) + generator.generate('''«folder»/«name».tdltx''', ''' + /* + * This is an example model + */ + Package «name» { + «imports» + + } + ''') + open('''«folder»/«name».tdltx''') + } else { + generator.generate('''«folder»/«name».tdltx''', "") + } } } -@FileTemplate(label="Data definitions import from OpenAPI", icon="file_template.png", description="Create a new package for TDLtx from OpenAPI data definitions.") -final class TDLtxFileFromOpenAPI { - //TODO: more modern way? - val s = new ScopedPreferenceStore(new InstanceScope(), "org.etsi.mts.tdl.tx.ui.template.data.openapi") - val lastUsed = "LAST_USED" - //TODO: file prompt? - val dataDefinitionsPath = text("Data Definitions Path:", s.getString(lastUsed), "The data definitions path to import from") - val sourceMapping = text("Source mapping tag:", "SOURCE_MAPPING", "The source mapping tag to be used for the data mappings") - val targetMapping = text("Target mapping tag:", "TARGET_MAPPING", "The target mapping tag to be used for the data mappings") - - var validated = false - - override protected updateVariables() { - validated = true - s.setValue(lastUsed, dataDefinitionsPath.value) - s.save() - super.updateVariables() - } - - override generateFiles(IFileGenerator generator) { - //NOTE: this is triggered on every key stroke.. -> lock until second screen - if (validated) { - generator.generate('''«folder»/«name».tdltx''', - ConverterNext.processToString(dataDefinitionsPath.value, - folder+"/"+name+".tdltx", - sourceMapping.value, - targetMapping.value - )) +@FileTemplate(label="TDL Textual with Standard TDL Libraries and Test Purpose Description Example", icon="file_template.png", description="Create a new textual file for TDL importing standard libraries for TDL and including a Test Purpose Description Example.") +final class TDLtxFileWithTPD { + + //TODO: reuse? + override generateFiles(IFileGenerator generator) { + if (generator instanceof WorkspaceFileGenerator) { + generator.addLibraries("TDL", folder) + //TODO: add possibility to reuse library selection + var imports = "Import all from TDL\n" + //TODO: extract for reuse? + generator.generate('''«folder»/«name».tdltx''', ''' + /* + * This is an example package + */ + Package «name» { + «imports» + //Example definitions to get started + Message Gate api accepts String + + Component node { + gate api http + } + + Configuration nodeTC { + node sut as SUT, + node tester as Tester, + connect server=sut::http to client=tester::http + } + + @PICS Boolean F1 + @PICS Boolean F2 + + Objective TO_01 { + Description: "Test document generation" + References: "Epic #xy" + } + + Test Purpose Description TP_01 { + Objective: TO_01 + Configuration: nodeTC + PICS: (F1 or F2) on tester + Initial conditions + with { + client sends "initiate" to server + } + + Expected behaviour + ensure that { + when { + client sends "request" to server + } + then { + client receives "response" from server + } + } + } + } + ''') + open('''«folder»/«name».tdltx''') + } else { + generator.generate('''«folder»/«name».tdltx''', "") } } - } diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProject.xtend b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProject.xtend index 755d37647fca9f7e12e7b666f0cc06434423a2df..f99351612d7febe32ecd81a274ea45b46885b887 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProject.xtend +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProject.xtend @@ -18,9 +18,8 @@ import org.eclipse.ui.ide.IDE import org.eclipse.swt.widgets.Display //TODO: customise -@ProjectTemplate(label="TDLtx", icon="project_template.png", description="

    TDLtx

    -

    This is a parameterized project for TDLtx. You can set a parameter to modify the content in the generated file -and a parameter to set the path the file is created in.

    ") +@ProjectTemplate(label="TDL Textual", icon="project_template.png", description="

    TDL Textual Plain Template

    +

    Plain project template without any example content.

    ") final class TDLtxProject { //TODO: remove after testing val advanced = check("Advanced:", false) @@ -113,7 +112,7 @@ final class TDLtxProject { } protected override List> getImages() { - #["project_template.png".image] + #["project_template_empty.png".image] } private def image(String id) { id -> pluginImageHelper.getImage('''platform:/plugin/«TxActivator.PLUGIN_ID»/«id»''') diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectBase.xtend b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectBase.xtend index 4f384274921f0bf5b75b0f3204e7bddb8443bdf6..5a085f7c66f42f42971fc651cf6e21d201b2df07 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectBase.xtend +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectBase.xtend @@ -18,9 +18,8 @@ import org.eclipse.ui.ide.IDE import org.eclipse.swt.widgets.Display //TODO: customise -@ProjectTemplate(label="TDLtx Base", icon="project_template.png", description="

    TDLtx

    -

    This is a parameterized project for TDLtx. You can set a parameter to modify the content in the generated file -and a parameter to set the path the file is created in.

    ") +@ProjectTemplate(label="TDL Textual for Test Purposes (TDL-TO)", icon="project_template.png", description="

    TDL Textual for Test Purposes using TDL-TO

    +

    Project template for Test Purpose specification using TDL-TO, includes an example Test Purpose to get started.

    ") final class TDLtxProjectBase { //TODO: remove after testing val advanced = check("Advanced:", false) @@ -88,9 +87,35 @@ final class TDLtxProjectBase { */ Package «name» { «imports» - //example type - Type float - //define additional elements here + //Example definitions to get started + Entity IUT + Event ready + Event connected + Event requests + Event receives + + //Example test purpose specification as a structured test objective + Test Purpose TP_01 { + Objective: "Check that the connection is initiated" + Reference: "ES 999 999" + Initial conditions + with { + the IUT entity being ready + } + Expected behaviour + ensure that { + when { + the IUT entity requests a connection + } + then { + the IUT entity receives a confirmation + } + } + Final conditions + with { + the IUT entity being connected + } + } } ''') ]) @@ -113,7 +138,7 @@ final class TDLtxProjectBase { } protected override List> getImages() { - #["project_template.png".image] + #["project_template_to.png".image] } private def image(String id) { id -> pluginImageHelper.getImage('''platform:/plugin/«TxActivator.PLUGIN_ID»/«id»''') diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectBaseTPD.xtend b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectBaseTPD.xtend new file mode 100644 index 0000000000000000000000000000000000000000..09784ecab5062e1bae8b8c0ea36d444a0dfe4b4f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectBaseTPD.xtend @@ -0,0 +1,158 @@ +package org.etsi.mts.tdl.ui.wizard +import org.eclipse.xtext.ui.wizard.template.ProjectTemplate +import com.google.inject.Inject +import org.eclipse.xtext.ui.PluginImageHelper +import org.eclipse.core.runtime.Status +import static org.eclipse.core.runtime.IStatus.* +import org.eclipse.xtext.ui.wizard.template.IProjectGenerator +import org.eclipse.xtext.ui.util.PluginProjectFactory +import org.eclipse.jdt.core.JavaCore +import org.eclipse.xtext.ui.XtextProjectHelper +import org.etsi.mts.tdl.tx.ui.internal.TxActivator +import org.eclipse.swt.graphics.Image +import java.util.List +import org.eclipse.core.resources.ResourcesPlugin +import org.eclipse.core.runtime.Path +import org.eclipse.ui.PlatformUI +import org.eclipse.ui.ide.IDE +import org.eclipse.swt.widgets.Display + +//TODO: customise +@ProjectTemplate(label="TDL Textual for Test Purpose Descriptions", icon="project_template.png", description="

    TDL Textual for Test Purpose Descriptions

    +

    Project template for Test Purpose Description specification using TDL-TO, includes an example Test Purpose Description to get started.

    Package Example {\n ...\n}

    ") +final class TDLtxProjectBaseTPD { + //TODO: remove after testing + val advanced = check("Advanced:", false) + val advancedGroup = group("Properties") +// val name = combo("Package Name:", #["Example", "Sample", "Tutorial", "Pack"], "The name of the package", advancedGroup) + val name = text("Main Package Name:", "Main", "The name of the main package") + val path = text("Path:", "tdl", "The package path to place the files in", advancedGroup) + //TODO: add other options + val importStandard = check("Import TDL Library", true, "Import TDL standard library definitions.", advancedGroup) + val importHTTP = check("Import HTTP Library", false, "Import TDL HTTP library definitions.", advancedGroup) + val extendedNature = check("Add additional natures", false, "Add Eclipse Plug-in and Java natures", advancedGroup) + + @Inject + PluginImageHelper pluginImageHelper + + override protected updateVariables() { + name.enabled = advanced.value + path.enabled = advanced.value + importStandard.enabled = advanced.value + importHTTP.enabled = advanced.value + extendedNature.enabled = advanced.value + if (!advanced.value) { + name.value = "Main" + path.value = "tdl" + importStandard.value = true + importHTTP.value = false + extendedNature.value = false + } + } + + override protected validate() { + //TODO: validate name as well + if (path.value.matches('[a-z][a-z0-9_.]*(/[a-z][a-z0-9_.]*)*')) + null + else + new Status(ERROR, "Wizard", "'" + path + "' is not a valid package name") + //TODO: validate data definitions as well + } + + override generateProjects(IProjectGenerator generator) { + generator.generate(new PluginProjectFactory => [ + projectName = projectInfo.projectName + location = projectInfo.locationPath + projectNatures += #[XtextProjectHelper.NATURE_ID] + builderIds += #[XtextProjectHelper.BUILDER_ID] + if (extendedNature.value) { + projectNatures += #[JavaCore.NATURE_ID, "org.eclipse.pde.PluginNature"] + builderIds += #[JavaCore.BUILDER_ID] + } + folders += "src" + //TODO: remove hardcoded import + var imports = "" + if (importStandard.value) { + addFile('''src/«path»/TDL.tdltx''', TemplateHelper.getLibrary("TDL")) + imports += "Import all from TDL\n" + } + if (importHTTP.value) { + addFile('''src/«path»/HTTP.tdltx''', TemplateHelper.getLibrary("HTTP")) + imports += "Import all from HTTP\n" + imports += "Import all from HTTP.MessageBased\n" + } + addFile('''src/«path»/«name».tdltx''', ''' + /* + * This is an example package + */ + Package «name» { + «imports» + //Example definitions to get started + Message Gate api accepts String + + Component node { + gate api http + } + + Configuration nodeTC { + node sut as SUT, + node tester as Tester, + connect server=sut::http to client=tester::http + } + + @PICS Boolean F1 + @PICS Boolean F2 + + Objective TO_01 { + Description: "Test document generation" + References: "Epic #xy" + } + + Test Purpose Description TP_01 { + Objective: TO_01 + Configuration: nodeTC + PICS: (F1 or F2) on tester + Initial conditions + with { + client sends "initiate" to server + } + + Expected behaviour + ensure that { + when { + client sends "request" to server + } + then { + client receives "response" from server + } + } + } + } + ''') + ]) + //TODO: make more robust and share among other templates + open(projectInfo.projectName+"/src/"+path+"/"+name+".tdltx") + } + + private def open(String filePath) { + val path = new Path(filePath) + val ifile=ResourcesPlugin.getWorkspace().getRoot().getFile(path) +// val page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + val page = PlatformUI.workbench.workbenchWindows.get(0).activePage + Display.^default.asyncExec(new Runnable() { + + override run() { + IDE.openEditor(page, ifile) + } + + }) + } + + protected override List> getImages() { + #["project_template_tpd.png".image] + } + private def image(String id) { + id -> pluginImageHelper.getImage('''platform:/plugin/«TxActivator.PLUGIN_ID»/«id»''') + } + +} diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectTemplateProvider.xtend b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectTemplateProvider.xtend index 3b47c33a2daf29794b4225585d5aea6c53cd0e01..307487f885b86811d9f9b845e6248dd1756b56a4 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectTemplateProvider.xtend +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectTemplateProvider.xtend @@ -18,6 +18,9 @@ class TDLtxProjectTemplateProvider implements IProjectTemplateProvider { @Inject TDLtxProjectBase iTDLtxProjectBase + @Inject + TDLtxProjectBaseTPD iTDLtxProjectBaseTPD + @Inject TDLtxProjectWithOpenAPI iTDLtxProjectWithOpenAPI @@ -28,6 +31,7 @@ class TDLtxProjectTemplateProvider implements IProjectTemplateProvider { // new TDLtxProjectWithOpenAPI iTDLtxProject, iTDLtxProjectBase, + iTDLtxProjectBaseTPD, iTDLtxProjectWithOpenAPI ] } diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectWithOpenAPI.xtend b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectWithOpenAPI.xtend index 9059ebdc5c180e3a1bf27738a7c6374868f4e7fb..79425978a37be53e3d99b81028a51942618f12fb 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectWithOpenAPI.xtend +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TDLtxProjectWithOpenAPI.xtend @@ -12,7 +12,6 @@ import org.eclipse.xtext.ui.XtextProjectHelper import org.eclipse.xtext.ui.util.PluginProjectFactory import org.eclipse.xtext.ui.wizard.template.IProjectGenerator import org.eclipse.xtext.ui.wizard.template.ProjectTemplate -import org.etsi.mts.tdl.openapi2tdl.next.ConverterNext import org.etsi.mts.tdl.tx.ui.internal.TxActivator import org.eclipse.core.resources.ResourcesPlugin import org.eclipse.core.runtime.Path @@ -21,12 +20,10 @@ import org.eclipse.ui.ide.IDE import org.eclipse.swt.widgets.Display import static org.eclipse.core.runtime.IStatus.* - +import static extension org.etsi.mts.tdl.ui.wizard.WizardHelper.* //TODO: customise further, reuse? -@ProjectTemplate(label="TDLtx with OpenAPI", icon="project_template.png", description="

    TDLtx with OpenAPI

    -

    This is a parameterized project for TDLtx with the option to import data definitions from OpenAPI. -You can set a parameter to modify the content in the generated file -and a parameter to set the path the file is created in.

    ") +@ProjectTemplate(label="TDL Textual for Executable Tests", icon="project_template.png", description="

    TDL Textual for Executable Tests

    +

    Project template for executable tests.

    ") final class TDLtxProjectWithOpenAPI { //TODO: more modern way? //TODO: differentiate for project vs file wizard @@ -133,6 +130,8 @@ final class TDLtxProjectWithOpenAPI { */ Package «name» { «imports» + //TODO: include example executable test specification, + //TODO: setup nature and generation } ''') @@ -140,23 +139,9 @@ final class TDLtxProjectWithOpenAPI { //TODO: make more robust and share among other templates open(projectInfo.projectName+"/src/"+path+"/"+name+".tdltx") } - - private def open(String filePath) { - val path = new Path(filePath) - val ifile=ResourcesPlugin.getWorkspace().getRoot().getFile(path) -// val page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - val page = PlatformUI.workbench.workbenchWindows.get(0).activePage - Display.^default.asyncExec(new Runnable() { - - override run() { - IDE.openEditor(page, ifile) - } - - }) - } - + protected override List> getImages() { - #["project_template.png".image] + #["project_template_tri.png".image] } private def image(String id) { id -> pluginImageHelper.getImage('''platform:/plugin/«TxActivator.PLUGIN_ID»/«id»''') diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TemplateHelper.java b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TemplateHelper.java index 1df5bcc259e45e944f95d65d9b0fa37b8040be16..09eec158906b474781e8e52480ecaf563d7c580a 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TemplateHelper.java +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/TemplateHelper.java @@ -1,41 +1,72 @@ package org.etsi.mts.tdl.ui.wizard; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.nio.file.Files; -import java.nio.file.Path; +import org.eclipse.core.internal.resources.WorkspaceRoot; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Platform; +import org.eclipse.xtext.ui.wizard.template.IFileGenerator; +import org.eclipse.xtext.ui.wizard.template.WorkspaceFileGenerator; import org.eclipse.xtext.xbase.lib.Exceptions; +import org.etsi.mts.tdl.resources.ResourceHandler; import org.osgi.framework.Bundle; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.Path; public class TemplateHelper { enum Libraries { Standard, HTTP } + + //reimplemented in Xtend + public static boolean checkIfFileExists(String path, IFileGenerator generator) { + WorkspaceFileGenerator gen = (WorkspaceFileGenerator) generator; + WorkspaceRoot root = (WorkspaceRoot) gen.getRule(); + Path target = new Path(path); + return root.exists(target); + } + public static String getLibrary(String name) { - String library = ""; + String library = "//NOT AVAILABLE\n"; try { - System.out.println("Get standard library..."); - String absolutePath = Path.of("templates/"+name+".tdltx").toFile().getAbsolutePath(); - System.out.println(" Path: " + absolutePath); - String source = "templates/"+name+".tdltx"; - URI uri = new File(source).toURI(); + //src at runtime, but no src at install time? + String libraryPath = "org/etsi/mts/tdl/library/"+name+".tdltx"; + URI uri; if (Platform.isRunning()) { - System.out.println("Running as plugin..."); - Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.tx.ui"); - URL url = bundle.getEntry(source); - uri = FileLocator.toFileURL(url).toURI(); + //TODO: externalise + //TODO: check if resolved? +// BundleContext context = bundle.getBundleContext(); + //TODO: this is a bit flaky, but seems to work both at install and at runtime + //TODO: try with resource handler as well or outsorce to resource handler? +// uri = ResourceHandler.getSourceUri(TemplateHelper.class, "org.etsi.mts.tdl.library", libraryPath); +// ILog.get().info("Library URI:"+uri); + String pluginId = "org.etsi.mts.tdl.library"; + String content = ResourceHandler.getContentFromPlugin(libraryPath, pluginId); + library = content; + //TODO: this does not seem to work if there are spaces in the path +// org.eclipse.core.runtime.Path libPath = new org.eclipse.core.runtime.Path(libraryPath); +// Bundle bundle = Platform.getBundle("org.etsi.mts.tdl.library"); +// URL libURL = FileLocator.find(bundle, libPath); +// uri = FileLocator.resolve(libURL).toURI(); +// File file = new File(FileLocator.resolve(libURL).toURI()); +// library = Files.readString(Path.of(uri)); } else { - System.out.println("Get from class localtion..."); + System.out.println("Get from class localtion..."); + //TODO: this needs to be revised.. currently libraries in two locations.. + //TODO: extract and reuse in ResoureHandler? String binPath = TemplateContent.class.getClass().getProtectionDomain().getCodeSource() .getLocation().getPath(); String projectPath = new File(binPath).getParent(); - uri = new File(((projectPath + "/") + source)).toURI(); + uri = new File(((projectPath + "/") + libraryPath)).toURI(); + library = Files.readString(java.nio.file.Path.of(uri)); } - library = Files.readString(Path.of(uri)); } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/WizardHelper.xtend b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/WizardHelper.xtend new file mode 100644 index 0000000000000000000000000000000000000000..79972bc3c38eafd6122bbe7346dafaab9e55cc5f --- /dev/null +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/WizardHelper.xtend @@ -0,0 +1,43 @@ +package org.etsi.mts.tdl.ui.wizard + +import org.eclipse.xtext.ui.wizard.template.IFileGenerator +import org.eclipse.xtext.ui.wizard.template.WorkspaceFileGenerator +import org.eclipse.core.internal.resources.WorkspaceRoot +import org.eclipse.core.runtime.Path +import org.eclipse.core.resources.ResourcesPlugin +import org.eclipse.ui.PlatformUI +import org.eclipse.swt.widgets.Display +import org.eclipse.ui.ide.IDE +import org.etsi.mts.tdl.resources.FileFinder + +class WizardHelper { + static def void addLibraries(IFileGenerator generator, String library, String folder) { + val target = '''«folder»/«library».tdltx''' + if (!generator.checkIfFileExists(target)) { + generator.generate(target, TemplateHelper.getLibrary("TDL")) + } + } + + static def boolean checkIfFileExists(IFileGenerator generator, String path) { + //TODO: check in whole project + val root = ((generator as WorkspaceFileGenerator).rule as WorkspaceRoot) + val p = new Path(path) + val project = root.getProject(p.segment(0)) + val FileFinder finder = [it|it.name.contains(p.lastSegment)] + project.accept(finder); + return finder.file !== null + } + + static def open(String filePath) { + val path = new Path(filePath) + val file = ResourcesPlugin.getWorkspace().getRoot().getFile(path) + // val page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + val page = PlatformUI.workbench.workbenchWindows.get(0).activePage + Display.^default.asyncExec(new Runnable() { + override run() { + IDE.openEditor(page, file) + } + + }) + } +} diff --git a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/messages.properties b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/messages.properties index 3bd4eb372baf6548e8acf74cde5a6d9d62a1916c..a3041092d3ec7d8529b54601c6e28f5e09512d4a 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/messages.properties +++ b/plugins/org.etsi.mts.tdl.tx.ui/src/org/etsi/mts/tdl/ui/wizard/messages.properties @@ -1,14 +1,22 @@ -TDLtxProject_Label=TDLtx -TDLtxProject_Description=

    TDLtx

    This is a parameterized project for TDLtx. You can set a parameter to modify the content in the generated file and a parameter to set the path the file is created in.

    -TDLtxFile_Label=TDLtx -TDLtxFile_Description=Create a new package for TDLtx. +TDLtxProject_Label=TDL Textual +TDLtxProject_Description=

    TDL Textual Plain Template

    Plain project template without any example content.

    +TDLtxFile_Label=TDL Textual +TDLtxFile_Description=Create a new textual file for TDL. TDLtxFileExtras_Label=Data definitions import from OpenAPI TDLtxFileExtras_Description=Create a new package for TDLtx from OpenAPI data definitions. -TDLtxProjectWithOpenAPI_Label=TDLtx with OpenAPI -TDLtxProjectWithOpenAPI_Description=

    TDLtx with OpenAPI

    This is a parameterized project for TDLtx with the option to import data definitions from OpenAPI. You can set a parameter to modify the content in the generated file and a parameter to set the path the file is created in.

    -TDLtxFileFromOpenAPI_Label=Data definitions import from OpenAPI -TDLtxFileFromOpenAPI_Description=Create a new package for TDLtx from OpenAPI data definitions. -TDLtxLibrary_Label=TDLtx Library +TDLtxProjectWithOpenAPI_Label=TDL Textual for Executable Tests +TDLtxProjectWithOpenAPI_Description=

    TDL Textual for Executable Tests

    Project template for executable tests.

    +TDLtxFileFromOpenAPI_Label=TDL Textual with Standard TDL Libraries and Test Purpose Description Example +TDLtxFileFromOpenAPI_Description=Create a new textual file for TDL importing standard libraries for TDL and including a Test Purpose Description Example. +TDLtxLibrary_Label=TDL Textual Library TDLtxLibrary_Description=Add library for TDL. -TDLtxProjectBase_Label=TDLtx Base -TDLtxProjectBase_Description=

    TDLtx

    This is a parameterized project for TDLtx. You can set a parameter to modify the content in the generated file and a parameter to set the path the file is created in.

    +TDLtxProjectBase_Label=TDL Textual for Test Purposes (TDL-TO) +TDLtxProjectBase_Description=

    TDL Textual for Test Purposes using TDL-TO

    Project template for Test Purpose specification using TDL-TO, includes an example Test Purpose to get started.

    +TDLtxProjectBaseTPD_Label=TDL Textual for Test Purpose Descriptions +TDLtxProjectBaseTPD_Description=

    TDL Textual for Test Purpose Descriptions

    Project template for Test Purpose Description specification using TDL-TO, includes an example Test Purpose Description to get started.

    Package Example { ... }

    +TDLtxProjectExecutable_Label=TDL Textual Project for Executable Tests +TDLtxProjectExecutable_Description=

    TDL Textual for Executable Tests

    TODO: This is a parameterized project for TDL Textual. You can set a parameter to modify the content in the generated file and a parameter to set the path the file is created in.

    +TDLtxFileWithStandardLibrary_Label=TDL Textual with Standard TDL Libraries +TDLtxFileWithStandardLibrary_Description=Create a new textual file for TDL importing standard libraries for TDL. +TDLtxFileWithTPD_Label=TDL Textual with Standard TDL Libraries and Test Purpose Description Example +TDLtxFileWithTPD_Description=Create a new textual file for TDL importing standard libraries for TDL and including a Test Purpose Description Example. diff --git a/plugins/org.etsi.mts.tdl.tx.ui/templates/templates.xml b/plugins/org.etsi.mts.tdl.tx.ui/templates/templates.xml index fa5eee19c7925bcc1dffad0429695846c4a3c8eb..036eb1d830b63d20c2c20f901fdedce411d74a1f 100644 --- a/plugins/org.etsi.mts.tdl.tx.ui/templates/templates.xml +++ b/plugins/org.etsi.mts.tdl.tx.ui/templates/templates.xml @@ -101,7 +101,7 @@ with {