diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..0929e2b17f43180aebf64d7089941a6fd37e7df5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.gradle/ +src/gen +.idea/ +build/ +out/ +logs/ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..32ff87ebd78416b9397a39a35906e4d7e3c48a0c --- /dev/null +++ b/build.gradle @@ -0,0 +1,155 @@ +// General configuration (plugins, settings, dependencies) +group 'de.tudresden.inf.st' +version '0.1' + +apply plugin: 'java' +apply plugin: 'java-library' +apply plugin: 'jastadd' +apply plugin: 'application' +apply plugin: "idea" +apply plugin: 'java-library' + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +repositories.mavenCentral() + +buildscript { + repositories.mavenCentral() + dependencies { + classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3' + } +} + +idea.module.generatedSourceDirs += file('src/gen/java') + +sourceSets.main.java.srcDir "src/gen/java" +jar.manifest.attributes('Main-Class': 'de.tudresden.inf.st.pnml.Main') + +dependencies { + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jackson_version}" + implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' + implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30' + implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.13.2' + implementation group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15' + + // pnml lib + implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore', version: '2.12.0' + implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore.xmi', version: '2.12.0' + implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.common', version: '2.12.0' + implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.mwe.core', version: '1.3.13' + api group: 'fr.lip6.pnml', name: 'fr.lip6.pnml.framework.ptnet', version: '2.2.12' + api group: 'fr.lip6.pnml', name: 'fr.lip6.pnml.framework.utils', version: '2.2.12' + implementation group: 'org.apache.ws.commons.axiom', name: 'axiom-api', version: '1.2.22' + implementation group: 'org.apache.ws.commons.axiom', name: 'axiom-impl', version: '1.2.22' + implementation group: 'com.thaiopensource', name: 'jing', version: '20091111' + implementation 'org.jetbrains:annotations:19.0.0' + + compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0' + + jastadd2 "org.jastadd:jastadd:2.3.4" +} + +// Default run configuration +run { + mainClassName = 'de.tudresden.inf.st.pnml.Main' + standardInput = System.in +} + +// Generated files +def ecoreFile = "./src/main/resources/placeTransition.ecore" +def relastAspect = "./src/gen/jastadd/pnml/placeTransition.ecore.jadd" +def relastFile = "./src/gen/jastadd/pnml/placeTransition.relast" + +// First phase: Ecore -> RelAst +task ecoreToRelast(type: JavaExec) { + group = 'Build' + main = "-jar" + + + doFirst { + delete "src/gen/jastadd" + mkdir "src/gen/jastadd/pnml" + } + + args "libs/ecore2relast-0.1.jar", ecoreFile, relastFile + + inputs.files file(ecoreFile) + outputs.files file(relastFile), file(relastAspect) +} + +// Second phase: RelAst -> JastAdd +task relastToJastAdd(type: JavaExec) { + group = 'Build' + main = "-jar" + + args "libs/relast.jar", + "--grammarName=./src/gen/jastadd/placeTransition", + "--useJastAddNames", + "--listClass=ArrayList", + "--jastAddList=JastAddList", + "--resolverHelper", + "--file", + relastFile, + "./src/main/jastadd/marking/Marking.relast", + "./src/main/jastadd/io/IoPN.relast" +} + +// Third phase: JastAdd -> Java (using JastAdd Gradle plugin) +jastadd { + configureModuleBuild() + modules { + module("pnml") { + + java { + basedir "src/" + include "main/**/*.java" + include "gen/**/*.java" + } + + jastadd { + basedir "src/" + include "main/jastadd/**/*.ast" + include "main/jastadd/**/*.jadd" + include "main/jastadd/**/*.jrag" + include "gen/jastadd/**/*.ast" + include "gen/jastadd/**/*.jadd" + include "gen/jastadd/**/*.jrag" + } + + scanner { + include "src/main/jastadd/PnmlScanner.flex" + } + + parser { + include "src/main/jastadd/PnmlParser.parser" + } + } + } + + cleanGen.doFirst { + delete "src/gen/java/de" + delete "src/gen-res/BuildInfo.properties" + } + + module = "pnml" + + astPackage = 'de.tudresden.inf.st.pnml.jastadd.model' + + genDir = 'src/gen/java' + + buildInfoDir = 'src/gen-res' + + scanner.genDir = "src/gen/java/de/tudresden/inf/st/pnml/jastadd/scanner" + parser.genDir = "src/gen/java/de/tudresden/inf/st/pnml/jastadd/parser" + +// default options are: '--rewrite=cnta', '--safeLazy', '--visitCheck=false', '--cacheCycle=false' + extraJastAddOptions = ['--List=JastAddList'] // '--incremental=param' +} + +// Workflow configuration for phases +relastToJastAdd.dependsOn ecoreToRelast +generateAst.dependsOn relastToJastAdd + +//// always run jastadd +//jastadd.outputs.upToDateWhen {false} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..8dfaf2b21cba4862b382e4bb5d7a3173956f99d0 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +jackson_version = 2.9.8 +apache_httpcomponents_version = 4.5.8 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..5c2d1cf016b3885f6930543d57b744ea8c220a1a Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..30bda3b74e65e2f3b2006eb11fb752c9395a977b --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Mar 27 11:59:50 CET 2020 +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000000000000000000000000000000000..83f2acfdc319a24e8766cca78f32474ad7a22dd6 --- /dev/null +++ b/gradlew @@ -0,0 +1,188 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000000000000000000000000000000000..9618d8d9607cd91a0efb866bcac4810064ba6fac --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/libs/dumpAst-0.3.3.jar b/libs/dumpAst-0.3.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..9db9b053aa1d931139e4bf83a1d1cfaa1e6e0dfb Binary files /dev/null and b/libs/dumpAst-0.3.3.jar differ diff --git a/libs/ecore2relast-0.1.jar b/libs/ecore2relast-0.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..0b4405335f990892b3a6731579d64b4698d3aec6 Binary files /dev/null and b/libs/ecore2relast-0.1.jar differ diff --git a/libs/ragconnect-0.2.5.jar b/libs/ragconnect-0.2.5.jar new file mode 100644 index 0000000000000000000000000000000000000000..459d1282cedfcd9502eb329c3596c31a3cca4173 Binary files /dev/null and b/libs/ragconnect-0.2.5.jar differ diff --git a/libs/relast.jar b/libs/relast.jar new file mode 100644 index 0000000000000000000000000000000000000000..a3430dfc1754b92676e2beb6b9f8ce4f1bb4429f Binary files /dev/null and b/libs/relast.jar differ diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..0d4ff7823810ae1346d8b16bcd15feefda06e314 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'pnml-splitter' diff --git a/src/gen-res/BuildInfo.properties b/src/gen-res/BuildInfo.properties new file mode 100644 index 0000000000000000000000000000000000000000..a2440a72cfa851ff722e40e349041a718103b316 --- /dev/null +++ b/src/gen-res/BuildInfo.properties @@ -0,0 +1,7 @@ +#Mon, 22 Mar 2021 15:24:06 +0100 + +moduleId=pnml +moduleName=null +moduleVariant=null +timestamp=2021-03-22T15\:24Z +build.date=2021-03-22 diff --git a/src/main/jastadd/Constraints.jrag b/src/main/jastadd/Constraints.jrag new file mode 100644 index 0000000000000000000000000000000000000000..f713c77bc4faad5090def9447b155f98b5e12452 --- /dev/null +++ b/src/main/jastadd/Constraints.jrag @@ -0,0 +1,91 @@ +aspect Constraints { + + coll Set<ConstraintViolation> PetriNet.constraintViolations() [new java.util.HashSet()] root PetriNet; + +} + +aspect ConstraintViolations { + + abstract class ConstraintViolation { + + + public String toString() { + return "Constraint " + getTitle() + " violated in object " + id() + ": " + getMessage(); + } + + protected ASTNode location; + + public String id() { + if (location instanceof PnObject) return ((PnObject) location).getId(); + if (location instanceof PetriNet) return ((PetriNet) location).getId(); + return location.toString(); + } + + protected String title; + protected String description; + protected String message; + + public String getTitle() { return title; } + public String getDescription() { return description; } + public String getMessage() { return message; } + + } + + class CheckIdsConstraint extends ConstraintViolation { + public CheckIdsConstraint(ASTNode location) { + this.location = location; + this.title = "CheckIds"; + this.description = "Checks id attribute existence"; + this.message = "A node of type '" + location.getClass().getSimpleName() + "' must have an id attribute."; + } + } + + class CheckIdUniquenessConstraint extends ConstraintViolation { + public CheckIdUniquenessConstraint(ASTNode location) { + this.location = location; + this.title = "CheckIdUniquess"; + this.description = "Checks id attribute uniqueness"; + this.message = "The id attribute value " + id() + " of the node of type '" + location.getClass().getSimpleName() + "' is not unique."; + } + } + + PetriNet contributes new CheckIdsConstraint(this) + when checkIdsConstraintViolated() + to PetriNet.constraintViolations(); + PnObject contributes new CheckIdsConstraint(this) + when checkIdsConstraintViolated() + to PetriNet.constraintViolations(); +} + +aspect CoreModelConstraints { + + syn boolean PetriNet.checkIdsConstraintViolated() = getId() == null || getId().equals(""); + syn boolean PnObject.checkIdsConstraintViolated() = getId() == null || getId().equals(""); + + coll List<String> PetriNet.ids() [new ArrayList()] root PetriNet; + PnObject contributes getId() to PetriNet.ids(); + + syn Map<String, Long> PetriNet.idCount() = + ids().stream().collect(Collectors.groupingBy(java.util.function.Function.identity(), Collectors.counting())); + + syn boolean PetriNet.uniqueId(String id) = idCount().get(id) <= 1; + syn boolean PnObject.uniqueId(String id) = petriNet().idCount().get(id) <= 1; + + syn Optional<CheckIdUniquenessConstraint> PetriNet.checkIdUniqueness() { + if(uniqueId(getId())) return Optional.empty(); + else return Optional.of(new CheckIdUniquenessConstraint(this)); + } + syn Optional<CheckIdUniquenessConstraint> PnObject.checkIdUniqueness() { + if(petriNet().uniqueId(getId())) return Optional.empty(); + else return Optional.of(new CheckIdUniquenessConstraint(this)); + } + + PetriNet contributes checkIdUniqueness().get() + when checkIdUniqueness().isPresent() + to PetriNet.constraintViolations(); + PnObject contributes checkIdUniqueness().get() + when checkIdUniqueness().isPresent() + to PetriNet.constraintViolations(); + + +} diff --git a/src/main/jastadd/Graphviz.jrag b/src/main/jastadd/Graphviz.jrag new file mode 100644 index 0000000000000000000000000000000000000000..07ca5fcfd74cf449178e5a55b0a77dbed2074be6 --- /dev/null +++ b/src/main/jastadd/Graphviz.jrag @@ -0,0 +1,42 @@ +aspect Graphviz { + syn String PetriNet.toDot() { + + StringBuffer b = new StringBuffer(); + + b.append("digraph \"").append(name()).append("\" {\n") + .append(" rankdir=LR;\n") + .append(" center=true; margin=1;\n") + .append("\n") + .append(" subgraph places {\n") + .append(" node [shape=circle,fixedsize=true,label=\"\", height=.3,width=.3];\n"); + + for (Place place : allPlaces()) { + b.append(" ").append(place.dotId()).append(" ["); + if (place.hasName()) b.append("xlabel=\"").append(place.name()).append("\", "); + b.append("label=\"").append("0").append("\"];\n"); + } + + b.append(" }\n\n"); + + b.append(" subgraph transitions {\n") + .append(" node [shape=rect,height=0.4,width=.4];\n"); + for (Transition transition : allTransitions()) { + b.append(" ").append(transition.dotId()).append(" ["); + if (transition.hasName()) b.append("label=\"").append(transition.name()).append("\""); + b.append("]\n"); + } + + b.append(" }\n\n"); + + for (Arc arc : allArcs()) { + b.append(" ").append(arc.getSource().dotId()).append("->").append(arc.getTarget().dotId()).append(";\n"); + } + b.append("}\n"); + + return b.toString(); + } + + syn String PetriNet.dotId() = "\"" + getId().replaceAll("\"", "\\\"") + "\""; + syn String PnObject.dotId() = "\"" + getId().replaceAll("\"", "\\\"") + "\""; + +} diff --git a/src/main/jastadd/Navigation.jrag b/src/main/jastadd/Navigation.jrag new file mode 100644 index 0000000000000000000000000000000000000000..38b4d06c7c82c1b90cd69591abaa68dc432e0c20 --- /dev/null +++ b/src/main/jastadd/Navigation.jrag @@ -0,0 +1,67 @@ +aspect Navigation { + inh PetriNet PnObject.petriNet(); + eq PetriNet.getChild().petriNet() = this; + + java.util.Collection<Place> Transition.incomingPlaces() { + java.util.Set<Place> incomingPlaces = new java.util.HashSet<>(); + for (Arc incomingArc : getInArcList()) { + incomingPlaces.add(incomingArc.getSource().asPlaceNode().place()); + } + return incomingPlaces; + } + + java.util.Collection<Place> Transition.outgoingPlaces() { + java.util.Set<Place> outgoingPlaces = new java.util.HashSet<>(); + for (Arc outgoingArc : getOutArcList()) { + outgoingPlaces.add(outgoingArc.getTarget().asPlaceNode().place()); + } + return outgoingPlaces; + } + + syn boolean Node.isPlaceNode() = false; + eq PlaceNode.isPlaceNode() = true; + + syn PlaceNode Node.asPlaceNode() = null; + eq PlaceNode.asPlaceNode() = this; + + syn boolean Node.isTransitionNode() = false; + eq TransitionNode.isTransitionNode() = true; + + syn TransitionNode Node.asTransitionNode() = null; + eq TransitionNode.asTransitionNode() = this; + + syn InputSignalTransition Transition.asInputSignalTransition() = null; + eq InputSignalTransition.asInputSignalTransition() = this; + + syn OutputSignalPlace Place.asOutputSignalPlace() = null; + eq OutputSignalPlace.asOutputSignalPlace() = this; + + syn Place PlaceNode.place(); + eq Place.place() = this; + eq RefPlace.place() = getRef().place(); + + syn Transition TransitionNode.transition(); + eq Transition.transition() = this; + eq RefTransition.transition() = getRef().transition(); + + coll java.util.Set<PnObject> PetriNet.allObjects() [new java.util.HashSet()] root PetriNet; + PnObject contributes this + to PetriNet.allObjects() + for petriNet(); + + coll java.util.Set<Place> PetriNet.allPlaces() [new java.util.HashSet()] root PetriNet; + Place contributes this + to PetriNet.allPlaces() + for petriNet(); + + coll java.util.Set<Transition> PetriNet.allTransitions() [new java.util.HashSet()] root PetriNet; + Transition contributes this + to PetriNet.allTransitions() + for petriNet(); + + coll java.util.Set<Arc> PetriNet.allArcs() [new java.util.HashSet()] root PetriNet; + Arc contributes this + to PetriNet.allArcs() + for petriNet(); + +} diff --git a/src/main/jastadd/References.jrag b/src/main/jastadd/References.jrag new file mode 100644 index 0000000000000000000000000000000000000000..bce6451f2d7dd420d92c767b7a282df31381a3b2 --- /dev/null +++ b/src/main/jastadd/References.jrag @@ -0,0 +1,18 @@ +aspect References { + + syn PnObject PetriNet.resolve(String id) { + for (PnObject object : allObjects()) { + if (object.getId().equals(id)) { + return object; + } + } + throw new RuntimeException(new de.tudresden.inf.st.pnml.PnmlParseException("Unable to resolve id " + id)); + } + + eq PnObject.globallyResolveArcByToken(String id) = (Arc) petriNet().resolve(id); + eq PnObject.globallyResolveNodeByToken(String id) = (Node) petriNet().resolve(id); + eq PnObject.globallyResolvePlaceNodeByToken(String id) = (PlaceNode) petriNet().resolve(id); + eq PnObject.globallyResolveTransitionNodeByToken(String id) = (TransitionNode) petriNet().resolve(id); + eq PnObject.globallyResolveRefPlaceByToken(String id) = (RefPlace) petriNet().resolve(id); + eq PnObject.globallyResolveRefTransitionByToken(String id) = (RefTransition) petriNet().resolve(id); +} diff --git a/src/main/jastadd/Util.jadd b/src/main/jastadd/Util.jadd new file mode 100644 index 0000000000000000000000000000000000000000..fb2cf4befd6e539ded5d88b88cb7c6940113b0d7 --- /dev/null +++ b/src/main/jastadd/Util.jadd @@ -0,0 +1,31 @@ +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import java.util.*; +import java.util.stream.Collectors; + +aspect Logging { + static Logger ASTNode.logger = LogManager.getLogger(ASTNode.class); +} + +aspect JastAddAPIExtension { + + /** + * removes the object from the AST, i.e. removes the reference from its parent to the object + * + * Please note that any intrinsic non-containment relations to the object are not removed. + * @return true, if the object had a parent. + */ + public boolean ASTNode.removeSelf() { + if (getParent() == null) { + return false; + } else { + for (int childIndex = 0; childIndex < getParent().numChildren(); childIndex++) { + if (getParent().getChild(childIndex) == this) { + getParent().removeChild(childIndex); + return true; + } + } + } + throw new RuntimeException("unable to remove child, because it was not contained in its parent!"); + } +} diff --git a/src/main/jastadd/distribution/DistributedPN.jadd b/src/main/jastadd/distribution/DistributedPN.jadd new file mode 100644 index 0000000000000000000000000000000000000000..08110b5376eb37090d0f6f6b758a15d967f8ec55 --- /dev/null +++ b/src/main/jastadd/distribution/DistributedPN.jadd @@ -0,0 +1,30 @@ +aspect PnDistribution { + + syn lazy String Transition.location() { + return de.tudresden.inf.st.pnml.ToolSpecificsParser.getLocationFromToolSpecifics(this.getToolspecificList()); + } + + syn lazy String Transition.type() { + return de.tudresden.inf.st.pnml.ToolSpecificsParser.getTransitionTypeFromToolSpecifics(this.getToolspecificList()); + } + + syn lazy String Place.location() { + return de.tudresden.inf.st.pnml.ToolSpecificsParser.getLocationFromToolSpecifics(this.getToolspecificList()); + } + + syn lazy String Place.type() { + return de.tudresden.inf.st.pnml.ToolSpecificsParser.getPlaceTypeFromToolSpecifics(this.getToolspecificList()); + } + + syn lazy Boolean Transition.isLimitedChannelTransition() { + return de.tudresden.inf.st.pnml.ToolSpecificsParser.isLimitedChannelTransitionType(this.getToolspecificList()); + } + + syn lazy int Transition.channelLimit() { + return de.tudresden.inf.st.pnml.ToolSpecificsParser.getLimitedChannelTransitionValue(this.getToolspecificList()); + } + + syn lazy String Transition.getTopic(){ + return de.tudresden.inf.st.pnml.ToolSpecificsParser.getTopic(this.getToolspecificList()); + } +} \ No newline at end of file diff --git a/src/main/jastadd/io/IoPN.jadd b/src/main/jastadd/io/IoPN.jadd new file mode 100644 index 0000000000000000000000000000000000000000..5a37d6028d8813d51b225921c1d3a24ac53d44c3 --- /dev/null +++ b/src/main/jastadd/io/IoPN.jadd @@ -0,0 +1,82 @@ +aspect IoPnExtension{ + + inh Marking OutputSignalPlace.marking(); + + eq PetriNetDoc.getChild().marking() = null; + + eq Marking.getPetriNet().marking() = this; + + inh Place OutputSignalBinding.containingPlace(); + + eq OutputSignalPlace.getOutputSignalBinding().containingPlace() = this; + + eq Page.getObject().containingPlace() = null; + + syn lazy JastAddList<InputSignalBinding> InputSignalTransition.getInputSignalBindingList() { + + JastAddList<InputSignalBinding> isBindings = de.tudresden.inf.st.postprocessing.IoPetriNetPostProcessor.parseInputSignalBindingDefinitions(this.getToolspecificList()); + + return isBindings; + } + + syn lazy JastAddList<OutputSignalBinding> OutputSignalPlace.getOutputSignalBindingList() { + + JastAddList<OutputSignalBinding> osBindings = de.tudresden.inf.st.postprocessing.IoPetriNetPostProcessor.parseOutputSignalBindingDefinitions(this.getToolspecificList()); + + return osBindings; + } + + // updates automatically based on dependencies to the corresponding place + syn String OutputSignalBinding.getOutputSignalValue(){ + + OutputSignalPlace osp = this.containingPlace().asOutputSignalPlace(); + Marking marking = osp.marking(); + MarkedPlace markedPlace = marking.resolvePlaceById(this.getPlaceID()); + + JastAddList<EqualityOutputMapping> eomList = this.getEqualityOMListNoTransform(); + JastAddList<ThresholdOutputMapping> tomList = this.getThresholdOMListNoTransform(); + JastAddList<RangeOutputMapping> romList = this.getRangeOMListNoTransform(); + + // eom + + int result = -1; + + for(EqualityOutputMapping eom : eomList){ + if((eom.getValue() == markedPlace.getMarking()) && result == -1){ + result = eom.getResult(); + break; + } + } + + // tom + + if(result > -1){ + for(ThresholdOutputMapping tom : tomList){ + if(tom.getValue() <= markedPlace.getMarking()){ + result = tom.getResult(); + break; + } + } + } + + // rom + + if(result > -1){ + for(RangeOutputMapping rom: romList){ + if((rom.getLowerBound() <= markedPlace.getMarking()) && (rom.getUpperBound() >= markedPlace.getMarking())){ + result = rom.getResult(); + break; + } + } + } + + // 0 (disabled Signal) is default + if(result == -1){ + result = 0; + } + + String output = String.valueOf(result) + "-" + this.getOutputSignalID(); + + return output; + } +} \ No newline at end of file diff --git a/src/main/jastadd/io/IoPN.relast b/src/main/jastadd/io/IoPN.relast new file mode 100644 index 0000000000000000000000000000000000000000..b659cb7a2cd2edc98e3a60b37e7059bd9b81f5ff --- /dev/null +++ b/src/main/jastadd/io/IoPN.relast @@ -0,0 +1,11 @@ +InputSignalBinding : PnObject ::= <TransitionID:String> <InputSignalID:String> <InputSignalValue:int>; +OutputSignalBinding : PnObject ::= <PlaceID:String> <OutputSignalID:String> /<OutputSignalValue:String>/ EqualityOM:EqualityOutputMapping* ThresholdOM:ThresholdOutputMapping* RangeOM:RangeOutputMapping*; + +InputSignalTransition : Transition ::= /InputSignalBinding*/; +OutputSignalPlace : Place ::= /OutputSignalBinding*/; + +OutputMapping; + +EqualityOutputMapping : OutputMapping ::= <Value:java.lang.Integer> <Result:java.lang.Integer>; +ThresholdOutputMapping : OutputMapping ::= <Value:java.lang.Integer> <Result:java.lang.Integer>; +RangeOutputMapping : OutputMapping ::= <UpperBound:java.lang.Integer> <LowerBound:java.lang.Integer> <Result:java.lang.Integer>; diff --git a/src/main/jastadd/marking/Execution.jadd b/src/main/jastadd/marking/Execution.jadd new file mode 100644 index 0000000000000000000000000000000000000000..e6bda62525b76b1f417843802a6ed622ac30ead5 --- /dev/null +++ b/src/main/jastadd/marking/Execution.jadd @@ -0,0 +1,99 @@ +import de.tudresden.inf.st.pnml.PnmlConstants; + +aspect Execution { + + public boolean Marking.fireInPlace() { + return fireInPlace(new Random()); + } + + public boolean Marking.fireInPlace(java.util.Random random) { + return fireInPlace(random, true).isPresent(); + } + + public Optional<Marking> Marking.fireTransition(Transition transition, boolean requireFlush) { + + if(transition.type().equals(PnmlConstants.TRANSITION_TYPE_DISCRETE)){ + + transition.incomingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()-1)); + transition.outgoingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()+1)); + + if (requireFlush) { + this.flushTreeCache(); + } + + return Optional.of(this); + } + return null; + } + + public Optional<Marking> Marking.fireChannelTransitionOutput(Transition transition, boolean requireFlush) { + + if(transition.type().equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_OUT) + || transition.type().equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT)){ + + transition.incomingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()-1)); + + if (requireFlush) { + this.flushTreeCache(); + } + + return Optional.of(this); + } + return null; + } + + public Optional<Marking> Marking.fireChannelTransitionInput(Transition transition, boolean requireFlush) { + + if(transition.type().equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) + || transition.type().equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_IN)){ + + transition.outgoingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()+1)); + + if (requireFlush) { + this.flushTreeCache(); + } + + return Optional.of(this); + } + return null; + } + + private Optional<Marking> Marking.fireInPlace(java.util.Random random, boolean requireFlush) { + if(enabledTransitions().isEmpty()) return Optional.empty(); + + // select a random transition + Transition transition = enabledTransitions().stream() + .sorted((t1, t2) -> t1.getId().compareTo(t2.getId())) + .skip(random.nextInt(enabledTransitions().size())) + .findFirst().get(); + + // take a token from each incoming place + transition.incomingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()-1)); + + // place a token in each outgoing place + transition.outgoingPlaces().forEach(place -> this.resolvePlace(place).setMarking(this.resolvePlace(place).getMarking()+1)); + + if (requireFlush) { + // flush the entire marking tree + this.flushTreeCache(); + } + + return Optional.of(this); + } + + public java.util.Collection<Place> Marking.collectIncomingPlace(Transition transition){ + return transition.incomingPlaces(); + } + + public java.util.Collection<Place> Marking.collectOutgoingPlace(Transition transition){ + return transition.outgoingPlaces(); + } + + public Optional<Marking> Marking.fire() { + return fire(new Random()); + } + + public Optional<Marking> Marking.fire(java.util.Random random) { + return treeCopyNoTransform().fireInPlace(random, false); + } +} diff --git a/src/main/jastadd/marking/Marking.jrag b/src/main/jastadd/marking/Marking.jrag new file mode 100644 index 0000000000000000000000000000000000000000..17c5f98908ce0dacea26bacc346e8a9d2fad9bf6 --- /dev/null +++ b/src/main/jastadd/marking/Marking.jrag @@ -0,0 +1,74 @@ +aspect Marking { + public Marking PetriNet.initialMarking(PetriNet pn) { + Marking marking = new Marking(); + marking.setPetriNet(pn); + for (Place place : allPlaces()) { + MarkedPlace markedPlace = new MarkedPlace(); + markedPlace.setPlace(place); + if (place.hasInitialMarking() && place.getInitialMarking().getText() != null) { + markedPlace.setMarking(place.getInitialMarking().getText()); + } else { + markedPlace.setMarking(0); + } + marking.addPlace(markedPlace); + } + return marking; + } + + public Marking PetriNet.setupMarking(PetriNet pn) { + + Marking marking = new Marking(); + marking.setPetriNet(pn); + + for (Place place : allPlaces()) { + + MarkedPlace markedPlace = new MarkedPlace(); + markedPlace.setPlace(place); + markedPlace.setMarking(1); + + marking.addPlace(markedPlace); + } + return marking; + } + + syn MarkedPlace Marking.resolvePlace(Place place) = placeMap().get(place); + + syn lazy java.util.Map<Place, MarkedPlace> Marking.placeMap() { + java.util.Map<Place, MarkedPlace> map = new java.util.HashMap<>(); + for (MarkedPlace markedPlace : getPlaceList()) { + map.put(markedPlace.getPlace(), markedPlace); + } + return map; + } + + syn MarkedPlace Marking.resolvePlaceById(String placeID) { + + for (MarkedPlace markedPlace : getPlaceList()) { + if(markedPlace.getPlace().getId().equals(placeID)){ + return markedPlace; + } + } + return null; + } + + syn int Marking.marking(Place place) = resolvePlace(place).getMarking(); + + syn boolean Marking.isEnabled(Transition t) { + for (Place place : t.incomingPlaces()) { + if (marking(place) == 0) return false; + } + return true; + } + + syn boolean Marking.isDead() { + for (Transition transition : getPetriNet().allTransitions()) { + if (isEnabled(transition)) return false; + } + return true; + } + + syn java.util.Set<Transition> Marking.enabledTransitions() + = getPetriNet().allTransitions().stream() + .filter(t -> isEnabled(t)) + .collect(Collectors.toSet()); +} diff --git a/src/main/jastadd/marking/Marking.relast b/src/main/jastadd/marking/Marking.relast new file mode 100644 index 0000000000000000000000000000000000000000..487b28226d7c9f73686ea4eb78495bbcee7bf488 --- /dev/null +++ b/src/main/jastadd/marking/Marking.relast @@ -0,0 +1,4 @@ +Marking ::= PetriNet:PetriNet Place:MarkedPlace*; +MarkedPlace ::= <Marking:int>; + +rel MarkedPlace.Place -> Place; diff --git a/src/main/jastadd/marking/Printing.jrag b/src/main/jastadd/marking/Printing.jrag new file mode 100644 index 0000000000000000000000000000000000000000..e89c16e4610fcfd8afaced338844e5f122b54f86 --- /dev/null +++ b/src/main/jastadd/marking/Printing.jrag @@ -0,0 +1,17 @@ +aspect Printing { + syn String Marking.print() { + StringBuilder b = new StringBuilder(); + b.append("Marking for Petri net '").append(getPetriNet().name()).append("':\n"); + for (MarkedPlace place : getPlaceList()) { + b.append(" ").append(place.getPlace().name()).append(": ").append(place.getMarking()).append("\n"); + } + b.append("Transitions for Petri net '").append(getPetriNet().name()).append("':\n"); + for (Transition trans : getPetriNet().allTransitions()) { + b.append(" ").append(trans.name()).append(": ").append(isEnabled(trans)?"true":"false").append("\n"); + } + return b.toString(); + } + + syn String PetriNet.name() = hasName()?getName().getText():getId(); + syn String PnObject.name() = hasName()?getName().getText():getId(); +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/Main.java b/src/main/java/de/tudresden/inf/st/pnml/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..f1358a44192b498e5d6ee23ad8d51933d43aa706 --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/Main.java @@ -0,0 +1,13 @@ +package de.tudresden.inf.st.pnml; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Main { + + private static final Logger logger = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) { + + } +} \ No newline at end of file diff --git a/src/main/java/de/tudresden/inf/st/pnml/PnmlConstants.java b/src/main/java/de/tudresden/inf/st/pnml/PnmlConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..956ffaa8191504651e31b32e462c1bca07102d86 --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/PnmlConstants.java @@ -0,0 +1,45 @@ +package de.tudresden.inf.st.pnml; + +public final class PnmlConstants { + + public static final String TRANSITION_TYPE_DISCRETE = "discreteTransitionType"; + public static final String TRANSITION_TYPE_CONTINUOUS = "continuousTransitionType"; + + public static final String TRANSITION_TYPE_CHANNEL_AC = "acChannelTransitionType"; + public static final String TRANSITION_TYPE_CHANNEL_NOT_AC = "notAcChannelTransitionType"; + public static final String TRANSITION_TYPE_CHANNEL_ACK_AC = "ackAcChannelTransitionType"; + public static final String TRANSITION_TYPE_CHANNEL_LIMITED_IN = "limitedChannelInType"; + public static final String TRANSITION_TYPE_CHANNEL_UNLIMITED_IN = "unlimitedChannelInType"; + + public static final String TRANSITION_TYPE_CHANNEL_LIMITED_OUT = "limitedChannelOutType"; + public static final String TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT = "unlimitedChannelOutType"; + + public static final String PLACE_TYPE_DISCRETE = "discretePlaceType"; + public static final String PLACE_TYPE_CONTINUOUS = "continuousPlaceType"; + + public static final String LOCATION_KEY = "location"; + public static final String TYPE_KEY = "type"; + public static final String LIMIT_KEY = "limit"; + public static final String TOPIC_KEY = "topic"; + + public static final String INPUT_SIGNAL_BINDINGS_KEY = "inputsignalbindings"; + public static final String OUTPUT_SIGNAL_BINDINGS_KEY = "outputsignalbindings"; + + public static final String INPUT_SIGNAL_BINDING_KEY = "inputsignalbinding"; + public static final String OUTPUT_SIGNAL_BINDING_KEY = "outputsignalbinding"; + + public static final String TRANSITION_ID_KEY = "transitionID"; + public static final String INPUT_SIGNAL_ID_KEY = "inputsignalID"; + public static final String PLACE_ID_KEY = "placeID"; + public static final String OUTPUT_SIGNAL_ID_KEY = "outputsignalID"; + public static final String CURRENT_VALUE_KEY = "initialvalue"; + + public static final String EQUAL_OS_KEY = "equal"; + public static final String RANGE_OS_KEY = "range"; + public static final String TRESHOLD_KEY = "threshold"; + + public static final String VALUE_KEY = "value"; + public static final String RESULT_KEY = "result"; + public static final String UPPER_BOUND_KEY = "upperbound"; + public static final String LOWER_BOUND_KEY = "lowerbound"; +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/PnmlParseException.java b/src/main/java/de/tudresden/inf/st/pnml/PnmlParseException.java new file mode 100644 index 0000000000000000000000000000000000000000..0af92a3440ba07e3b3b028e212960d89b6247e4b --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/PnmlParseException.java @@ -0,0 +1,17 @@ +package de.tudresden.inf.st.pnml; + +public class PnmlParseException extends Exception { + + public PnmlParseException(String message) { + super(message); + } + + public PnmlParseException(String message, Throwable cause) { + super(message, cause); + } + + public PnmlParseException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/PnmlParser.java b/src/main/java/de/tudresden/inf/st/pnml/PnmlParser.java new file mode 100644 index 0000000000000000000000000000000000000000..766adc5d2d9fbc9750efc0c97b3256813a79354b --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/PnmlParser.java @@ -0,0 +1,422 @@ +package de.tudresden.inf.st.pnml; + +import de.tudresden.inf.st.pnml.jastadd.model.*; + +public class PnmlParser { + + private final PetriNet petriNet; + + public PnmlParser(fr.lip6.move.pnml.ptnet.PetriNet source) throws PnmlParseException { + this.petriNet = getPetriNet(source); + petriNet.treeResolveAll(); + } + + public PetriNet getPetriNet() { + return petriNet; + } + + // the get methods + + private PetriNet getPetriNet(fr.lip6.move.pnml.ptnet.PetriNet source) throws PnmlParseException { + PetriNet result = new PetriNet(); + fillPetriNet(source, result); + return result; + } + + private Page getPage(fr.lip6.move.pnml.ptnet.Page source) throws PnmlParseException { + Page result = new Page(); + fillPage(source, result); + return result; + } + + private NodeGraphics getNodeGraphics(fr.lip6.move.pnml.ptnet.NodeGraphics source) { + NodeGraphics result = new NodeGraphics(); + fillNodeGraphics(source, result); + return result; + } + + private Line getLine(fr.lip6.move.pnml.ptnet.Line source) { + Line result = new Line(); + fillLine(source, result); + return result; + } + + private Fill getFill(fr.lip6.move.pnml.ptnet.Fill source) { + Fill result = new Fill(); + fillFill(source, result); + return result; + } + + private Dimension getDimension(fr.lip6.move.pnml.ptnet.Dimension source) { + Dimension result = new Dimension(); + fillDimension(source, result); + return result; + } + + private Offset getOffset(fr.lip6.move.pnml.ptnet.Offset source) { + Offset result = new Offset(); + fillOffset(source, result); + return result; + } + + private Position getPosition(fr.lip6.move.pnml.ptnet.Position source) { + Position result = new Position(); + fillPosition(source, result); + return result; + } + + private Name getName(fr.lip6.move.pnml.ptnet.Name source) { + Name result = new Name(); + fillName(source, result); + return result; + } + + private AnnotationGraphics getAnnotationGraphics(fr.lip6.move.pnml.ptnet.AnnotationGraphics source) { + AnnotationGraphics result = new AnnotationGraphics(); + fillAnnotationGraphics(source, result); + return result; + } + + private Font getFont(fr.lip6.move.pnml.ptnet.Font source) { + Font result = new Font(); + fillFont(source, result); + return result; + } + + private ToolInfo getToolInfo(fr.lip6.move.pnml.ptnet.ToolInfo source) { + ToolInfo result = new ToolInfo(); + fillToolInfo(source, result); + return result; + } + + private Node getNode(fr.lip6.move.pnml.ptnet.Node source) throws PnmlParseException { + if (source instanceof fr.lip6.move.pnml.ptnet.PlaceNode) { + return getPlaceNode((fr.lip6.move.pnml.ptnet.PlaceNode) source); + } else if (source instanceof fr.lip6.move.pnml.ptnet.TransitionNode) { + return getTransitionNode((fr.lip6.move.pnml.ptnet.TransitionNode) source); + } else { + throw new PnmlParseException("Encountered illegal unknown subtype of Node " + source.getClass().getCanonicalName()); + } + } + + private PlaceNode getPlaceNode(fr.lip6.move.pnml.ptnet.PlaceNode source) throws PnmlParseException { + if (source instanceof fr.lip6.move.pnml.ptnet.Place) { + return getPlace((fr.lip6.move.pnml.ptnet.Place) source); + } else if (source instanceof fr.lip6.move.pnml.ptnet.RefPlace) { + return getRefPlace((fr.lip6.move.pnml.ptnet.RefPlace) source); + } else { + throw new PnmlParseException("Encountered illegal unknown subtype of PlaceNode " + source.getClass().getCanonicalName()); + } + } + + private Place getPlace(fr.lip6.move.pnml.ptnet.Place source) { + Place result = new OutputSignalPlace(); + fillPlace(source, result); + return result; + } + + private PTMarking getPTMarking(fr.lip6.move.pnml.ptnet.PTMarking source) { + PTMarking result = new PTMarking(); + fillPTMarking(source, result); + return result; + } + + private RefPlace getRefPlace(fr.lip6.move.pnml.ptnet.RefPlace source) { + RefPlace result = new RefPlace(); + fillRefPlace(source, result); + return result; + } + + private TransitionNode getTransitionNode(fr.lip6.move.pnml.ptnet.TransitionNode source) throws PnmlParseException { + if (source instanceof fr.lip6.move.pnml.ptnet.Transition) { + return getTransition((fr.lip6.move.pnml.ptnet.Transition) source); + } else if (source instanceof fr.lip6.move.pnml.ptnet.RefTransition) { + return getRefTransition((fr.lip6.move.pnml.ptnet.RefTransition) source); + } else { + throw new PnmlParseException("Encountered illegal unknown subtype of TransitionNode " + source.getClass().getCanonicalName()); + } + } + + private RefTransition getRefTransition(fr.lip6.move.pnml.ptnet.RefTransition source) { + RefTransition result = new RefTransition(); + fillRefTransition(source, result); + return result; + } + + private Transition getTransition(fr.lip6.move.pnml.ptnet.Transition source) { + Transition result = new InputSignalTransition(); + fillTransition(source, result); + return result; + } + + private Arc getArc(fr.lip6.move.pnml.ptnet.Arc source) { + Arc result = new Arc(); + fillArc(source, result); + return result; + } + + private PTArcAnnotation getPTArcannotation(fr.lip6.move.pnml.ptnet.PTArcAnnotation source) { + PTArcAnnotation result = new PTArcAnnotation(); + fillPTAnnotation(source, result); + return result; + } + + private ArcGraphics getArcGraphics(fr.lip6.move.pnml.ptnet.ArcGraphics source) { + ArcGraphics result = new ArcGraphics(); + fillArcGraphics(source, result); + return result; + } + + private PnObject getPnObject(fr.lip6.move.pnml.ptnet.PnObject source) throws PnmlParseException { + if (source instanceof fr.lip6.move.pnml.ptnet.Page) { + return getPage((fr.lip6.move.pnml.ptnet.Page) source); + } else if (source instanceof Node) { + return getNode((fr.lip6.move.pnml.ptnet.Node) source); + } else if (source instanceof fr.lip6.move.pnml.ptnet.Arc) { + return getArc((fr.lip6.move.pnml.ptnet.Arc) source); + } else if (source instanceof fr.lip6.move.pnml.ptnet.Node) { + return getNode((fr.lip6.move.pnml.ptnet.Node) source); + } else { + throw new PnmlParseException("Encountered illegal unknown subtype of PnObject " + source.getClass().getCanonicalName()); + } + } + + // the fill methods + + private void fillPetriNet(fr.lip6.move.pnml.ptnet.PetriNet source, PetriNet result) throws PnmlParseException { + for (fr.lip6.move.pnml.ptnet.Page page : source.getPages()) { + result.addPage(getPage(page)); + } + if (source.getName() != null) { + result.setName(getName(source.getName())); + } + for (fr.lip6.move.pnml.ptnet.ToolInfo toolInfo : source.getToolspecifics()) { + result.addToolspecific(getToolInfo(toolInfo)); + } + + // if(source.getToolspecifics().size() > 0) { + // System.out.println("-->" + source.getToolspecifics()); + // } + + result.setId(source.getId()); + if (source.getType() == fr.lip6.move.pnml.ptnet.PNType.PTNET) { + result.setType(PNType.PTNET); + } else { + throw new PnmlParseException("Illegal Petri Net type '" + source.getType().getLiteral() + "' encountered."); + } + + } + + private void fillPage(fr.lip6.move.pnml.ptnet.Page source, Page result) throws PnmlParseException { + fillPnObject(source, result); + + for (fr.lip6.move.pnml.ptnet.PnObject object : source.getObjects()) { + result.addObject(getPnObject(object)); + } + if (source.getNodegraphics() != null) { + result.setNodeGraphics(getNodeGraphics(source.getNodegraphics())); + } + } + + private void fillPnObject(fr.lip6.move.pnml.ptnet.PnObject source, PnObject result) { + if (source.getName() != null) { + result.setName(getName(source.getName())); + } + for (fr.lip6.move.pnml.ptnet.ToolInfo toolInfo : source.getToolspecifics()) { + result.addToolspecific(getToolInfo(toolInfo)); + } + + result.setId(source.getId()); + } + + private void fillNodeGraphics(fr.lip6.move.pnml.ptnet.NodeGraphics source, NodeGraphics result) { + if (source.getPosition() != null) { + result.setPosition(getPosition(source.getPosition())); + } + if (source.getDimension() != null) { + result.setDimension(getDimension(source.getDimension())); + } + if (source.getFill() != null) { + result.setFill(getFill(source.getFill())); + } + if (source.getLine() != null) { + result.setLine(getLine(source.getLine())); + } + } + + private void fillLine(fr.lip6.move.pnml.ptnet.Line source, Line result) { + result.setColor(CSS2Color.valueOf(source.getColor().getName())); + result.setShape(LineShape.valueOf(source.getShape().getName())); + result.setWidth(source.getWidth()); + result.setStyle(LineStyle.valueOf(source.getStyle().getName())); + } + + private void fillFill(fr.lip6.move.pnml.ptnet.Fill source, Fill result) { + result.setColor(CSS2Color.valueOf(source.getColor().getName())); + result.setGradientcolor(CSS2Color.valueOf(source.getGradientcolor().getName())); + result.setGradientrotation(Gradient.valueOf(source.getGradientrotation().getName())); + result.setImage(source.getImage()); + } + + private void fillDimension(fr.lip6.move.pnml.ptnet.Dimension source, Dimension result) { + fillCoordinate(source, result); + } + + private void fillCoordinate(fr.lip6.move.pnml.ptnet.Coordinate source, Coordinate result) { + result.setX(source.getX()); + result.setY(source.getY()); + } + + private void fillOffset(fr.lip6.move.pnml.ptnet.Offset source, Offset result) { + fillCoordinate(source, result); + } + + private void fillPosition(fr.lip6.move.pnml.ptnet.Position source, Position result) { + fillCoordinate(source, result); + } + + private void fillName(fr.lip6.move.pnml.ptnet.Name source, Name result) { + fillAnnotation(source, result); + + result.setText(source.getText()); + } + + private void fillAnnotation(fr.lip6.move.pnml.ptnet.Annotation source, Annotation result) { + if (source.getAnnotationgraphics() != null) { + result.setAnnotationGraphics(getAnnotationGraphics(source.getAnnotationgraphics())); + } + fillLabel(source, result); + } + + private void fillLabel(fr.lip6.move.pnml.ptnet.Annotation source, Annotation result) { + for (fr.lip6.move.pnml.ptnet.ToolInfo info : source.getToolspecifics()) { + result.addToolspecific(getToolInfo(info)); + } + } + + private void fillAnnotationGraphics(fr.lip6.move.pnml.ptnet.AnnotationGraphics source, AnnotationGraphics result) { + if (source.getOffset() != null) { + result.setOffset(getOffset(source.getOffset())); + } + if (source.getFill() != null) { + result.setFill(getFill(source.getFill())); + } + if (source.getLine() != null) { + result.setLine(getLine(source.getLine())); + } + if (source.getFont() != null) { + result.setFont(getFont(source.getFont())); + } + } + + private void fillFont(fr.lip6.move.pnml.ptnet.Font source, Font result) { + result.setAlign(FontAlign.valueOf(source.getAlign().getName())); + result.setDecoration(FontDecoration.valueOf(source.getDecoration().getName())); + result.setFamily(CSS2FontFamily.valueOf(source.getFamily().getName())); + result.setRotation(source.getRotation()); + result.setSize(CSS2FontSize.valueOf(source.getSize().getName())); + result.setStyle(CSS2FontStyle.valueOf(source.getStyle().getName())); + result.setWeight(CSS2FontWeight.valueOf(source.getWeight().getName())); + } + + private void fillToolInfo(fr.lip6.move.pnml.ptnet.ToolInfo source, ToolInfo result) { + result.setTool(source.getTool()); + result.setVersion(source.getVersion()); + result.setFormattedXMLBuffer(source.getFormattedXMLBuffer()); + result.setToolInfoGrammarURI(source.getToolInfoGrammarURI()); + } + + private void fillPlace(fr.lip6.move.pnml.ptnet.Place source, Place result) { + fillPlaceNode(source, result); + + if (source.getInitialMarking() != null) { + result.setInitialMarking(getPTMarking(source.getInitialMarking())); + } + } + + private void fillPTMarking(fr.lip6.move.pnml.ptnet.PTMarking source, PTMarking result) { + fillAnnotation(source, result); + + // whatever this is supposed to be. they changed the Integer to Long + result.setText(Math.toIntExact(source.getText())); + } + + private void fillRefPlace(fr.lip6.move.pnml.ptnet.RefPlace source, RefPlace result) { + fillPlaceNode(source, result); + + result.setRef(PlaceNode.createRefDirection(source.getRef().getId())); + } + + private void fillPlaceNode(fr.lip6.move.pnml.ptnet.PlaceNode source, PlaceNode result) { + fillNode(source, result); + + for (fr.lip6.move.pnml.ptnet.RefPlace referencingPlace : source.getReferencingPlaces()) { + result.addReferencingPlace(RefPlace.createRefDirection(referencingPlace.getId())); + } + } + + private void fillRefTransition(fr.lip6.move.pnml.ptnet.RefTransition source, RefTransition result) { + fillTransitionNode(source, result); + + result.setRef(TransitionNode.createRefDirection(source.getRef().getId())); + } + + private void fillTransitionNode(fr.lip6.move.pnml.ptnet.TransitionNode source, TransitionNode result) { + fillNode(source, result); + + for (fr.lip6.move.pnml.ptnet.RefTransition refTransition : source.getReferencingTransitions()) { + result.addReferencingTransition(RefTransition.createRefDirection(refTransition.getId())); + } + } + + private void fillTransition(fr.lip6.move.pnml.ptnet.Transition source, Transition result) { + fillTransitionNode(source, result); + } + + private void fillNode(fr.lip6.move.pnml.ptnet.Node source, Node result) { + + fillPnObject(source, result); + + if (source.getNodegraphics() != null) { + result.setNodeGraphics(getNodeGraphics(source.getNodegraphics())); + } + + for (fr.lip6.move.pnml.ptnet.Arc outArc : source.getOutArcs()) { + result.addOutArc(Arc.createRefDirection(outArc.getId())); + } + for (fr.lip6.move.pnml.ptnet.Arc inArc : source.getInArcs()) { + result.addInArc(Arc.createRefDirection(inArc.getId())); + } + } + + private void fillArc(fr.lip6.move.pnml.ptnet.Arc source, Arc result) { + fillPnObject(source, result); + + if (source.getArcgraphics() != null) { + result.setArcGraphics(getArcGraphics(source.getArcgraphics())); + } + if (source.getInscription() != null) { + result.setInscription(getPTArcannotation(source.getInscription())); + } + + result.setSource(Node.createRefDirection(source.getSource().getId())); + result.setTarget(Node.createRefDirection(source.getTarget().getId())); + } + + private void fillPTAnnotation(fr.lip6.move.pnml.ptnet.PTArcAnnotation source, PTArcAnnotation result) { + fillAnnotation(source, result); + + // whatever this is supposed to be. they changed the Integer to Long + result.setText(Math.toIntExact(source.getText())); + } + + private void fillArcGraphics(fr.lip6.move.pnml.ptnet.ArcGraphics source, ArcGraphics result) { + for (fr.lip6.move.pnml.ptnet.Position position : source.getPositions()) { + result.addPosition(getPosition(position)); + } + if (source.getLine() != null) { + result.setLine(getLine(source.getLine())); + } + } + +} diff --git a/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java b/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java new file mode 100644 index 0000000000000000000000000000000000000000..3979a5928fdc47c4ad3b5819349c5c16dc20467a --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/pnml/ToolSpecificsParser.java @@ -0,0 +1,185 @@ +package de.tudresden.inf.st.pnml; + +import de.tudresden.inf.st.pnml.jastadd.model.JastAddList; +import de.tudresden.inf.st.pnml.jastadd.model.ToolInfo; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class ToolSpecificsParser { + + private static final Logger logger = LoggerFactory.getLogger(ToolSpecificsParser.class); + + public static String getLocationFromToolSpecifics(JastAddList<ToolInfo> toolInfos) { + + if (toolInfos.getNumChild() > 0) { + try { + Document doc = parseToolSpecifics(toolInfos); + NodeList locationList = doc.getElementsByTagName(PnmlConstants.LOCATION_KEY); + + if (locationList.getLength() > 0 && locationList.item(0) != null) { + return locationList.item(0).getTextContent(); + } + + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + } + + return ""; + } + + public static String getTransitionTypeFromToolSpecifics(JastAddList<ToolInfo> toolInfos) { + + if (toolInfos.getNumChild() > 0) { + try { + Document doc = parseToolSpecifics(toolInfos); + NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY); + + if (typeList.getLength() > 0 && typeList.item(0) != null) { + String type = typeList.item(0).getTextContent(); + if (type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_AC) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_ACK_AC) || + type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_NOT_AC) || !type.equals(PnmlConstants.TRANSITION_TYPE_CONTINUOUS) + || type.equals(PnmlConstants.TRANSITION_TYPE_DISCRETE) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) + || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_IN)|| type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_OUT) + || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT)) { + return type; + } else { + logger.error("Error: Invalid transition type configured."); + } + } + + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + } + + return ""; + } + + public static String getPlaceTypeFromToolSpecifics(JastAddList<ToolInfo> toolInfos) { + + if (toolInfos.getNumChild() > 0) { + try { + Document doc = parseToolSpecifics(toolInfos); + NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY); + + if (typeList.getLength() > 0 && typeList.item(0) != null) { + String type = typeList.item(0).getTextContent(); + if (type.equals(PnmlConstants.PLACE_TYPE_DISCRETE) || type.equals(PnmlConstants.PLACE_TYPE_CONTINUOUS)) { + return type; + } else { + logger.error("Error: Invalid transition type configured."); + } + } + + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + } + + return ""; + } + + public static Boolean isLimitedChannelTransitionType(JastAddList<ToolInfo> toolInfos) { + + if (toolInfos.getNumChild() > 0) { + try { + Document doc = parseToolSpecifics(toolInfos); + NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY); + + if (typeList.getLength() > 0 && typeList.item(0) != null) { + String type = typeList.item(0).getTextContent(); + if ( type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_IN) + || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_OUT) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT)) { + return true; + } else { + return false; + } + } + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + } + return false; + } + + public static String getTopic(JastAddList<ToolInfo> toolInfos) { + + if (toolInfos.getNumChild() > 0) { + try { + Document doc = parseToolSpecifics(toolInfos); + NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY); + NodeList topicList = doc.getElementsByTagName(PnmlConstants.TOPIC_KEY); + + if (typeList.getLength() > 0 && typeList.item(0) != null + && topicList.getLength() > 0 && topicList.item(0) != null) { + + String type = typeList.item(0).getTextContent(); + + if ( type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_IN) + || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_OUT) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_UNLIMITED_OUT)) { + return topicList.item(0).getTextContent(); + } + } + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + } + + logger.error("Error: Tried to get sender transition of non-channel transition."); + return null; + } + + public static int getLimitedChannelTransitionValue(JastAddList<ToolInfo> toolInfos) { + + if (toolInfos.getNumChild() > 0) { + try { + Document doc = parseToolSpecifics(toolInfos); + NodeList typeList = doc.getElementsByTagName(PnmlConstants.TYPE_KEY); + + if (typeList.getLength() > 0 && typeList.item(0) != null) { + String type = typeList.item(0).getTextContent(); + if (type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) || type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) + ||type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN) ||type.equals(PnmlConstants.TRANSITION_TYPE_CHANNEL_LIMITED_IN)) { + NodeList boundList = doc.getElementsByTagName(PnmlConstants.LIMIT_KEY); + return Integer.valueOf(boundList.item(0).getTextContent()); + } else { + return -1; + } + } + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + } + return -1; + } + + private static Document parseToolSpecifics(JastAddList<ToolInfo> toolInfos) throws ParserConfigurationException, SAXException, IOException { + + StringBuffer toolInfoStringBuffer = toolInfos.getChild(0).getFormattedXMLBuffer(); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + + Document doc = dBuilder.parse(fromStringBuffer(toolInfoStringBuffer)); + doc.getDocumentElement().normalize(); + + return doc; + } + + private static InputStream fromStringBuffer(StringBuffer buf) { + return new ByteArrayInputStream(buf.toString().getBytes()); + } +} \ No newline at end of file diff --git a/src/main/java/de/tudresden/inf/st/postprocessing/IoPetriNetPostProcessor.java b/src/main/java/de/tudresden/inf/st/postprocessing/IoPetriNetPostProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..310c538baa909c17cbb0c442eaf19bd868e8d2fe --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/postprocessing/IoPetriNetPostProcessor.java @@ -0,0 +1,255 @@ +package de.tudresden.inf.st.postprocessing; + +import de.tudresden.inf.st.pnml.PnmlConstants; +import de.tudresden.inf.st.pnml.jastadd.model.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class IoPetriNetPostProcessor implements PostProcessor<PetriNet> { + + private static final Logger logger = LoggerFactory.getLogger(IoPetriNetPostProcessor.class); + + public static JastAddList<InputSignalBinding> parseInputSignalBindingDefinitions(JastAddList<ToolInfo> toolInfos){ + + try { + Document doc = parseToolSpecifics(toolInfos); + return parseInputSignalBindingDefinitionsInternal(doc); + + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + + return null; + } + + private static JastAddList<InputSignalBinding> parseInputSignalBindingDefinitionsInternal(Document doc) { + + NodeList isBindingDefList = doc.getElementsByTagName(PnmlConstants.INPUT_SIGNAL_BINDINGS_KEY); + JastAddList<InputSignalBinding> jastAddBindingList = new JastAddList<>(); + + if (isBindingDefList.getLength() > 0 && isBindingDefList.item(0) != null) { + + Node isBindingsNode = isBindingDefList.item(0); + + + if (isBindingsNode.getNodeType() == Node.ELEMENT_NODE) { + + Element isBindingsElement = (Element) isBindingsNode; + + NodeList isBindingNodes = isBindingsElement.getElementsByTagName(PnmlConstants.INPUT_SIGNAL_BINDING_KEY); + + for (int i = 0; i < isBindingNodes.getLength(); i++) { + + Node isBindingNode = isBindingNodes.item(i); + Element isBindingElement = (Element) isBindingNode; + + String tID = isBindingElement.getElementsByTagName(PnmlConstants.TRANSITION_ID_KEY).item(0).getTextContent(); + String isID = isBindingElement.getElementsByTagName(PnmlConstants.INPUT_SIGNAL_ID_KEY).item(0).getTextContent(); + int cVal = Integer.valueOf(isBindingElement.getElementsByTagName(PnmlConstants.CURRENT_VALUE_KEY).item(0).getTextContent()); + + if(cVal != 1 && cVal != 0){ + logger.error("[PARSER] Initial value of input signal " + isID + " is not value. Falling back to 0."); + cVal = 0; + } + + InputSignalBinding isb = new InputSignalBinding(); + isb.setInputSignalValue(cVal); + isb.setInputSignalID(isID); + isb.setTransitionID(tID); + + jastAddBindingList.add(isb); + } + } + } + return jastAddBindingList; + } + + public static JastAddList<OutputSignalBinding> parseOutputSignalBindingDefinitions(JastAddList<ToolInfo> toolInfos){ + + try { + Document doc = parseToolSpecifics(toolInfos); + return parseOutputSignalBindingDefinitionsInternal(doc); + + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + + return null; + } + + private static JastAddList<OutputSignalBinding> parseOutputSignalBindingDefinitionsInternal(Document doc) { + + NodeList osBindingDefList = doc.getElementsByTagName(PnmlConstants.OUTPUT_SIGNAL_BINDINGS_KEY); + JastAddList<OutputSignalBinding> jastAddBindingList = new JastAddList<>(); + + if (osBindingDefList.getLength() > 0 && osBindingDefList.item(0) != null) { + + Node osBindingsNode = osBindingDefList.item(0); + + if (osBindingsNode.getNodeType() == Node.ELEMENT_NODE) { + + Element osBindingsElement = (Element) osBindingsNode; + + NodeList osBindingNodes = osBindingsElement.getElementsByTagName(PnmlConstants.OUTPUT_SIGNAL_BINDING_KEY); + + for (int i = 0; i < osBindingNodes.getLength(); i++) { + + Node osBindingNode = osBindingNodes.item(i); + Element osBindingElement = (Element) osBindingNode; + + String pID = osBindingElement.getElementsByTagName(PnmlConstants.PLACE_ID_KEY).item(0).getTextContent(); + String osID = osBindingElement.getElementsByTagName(PnmlConstants.OUTPUT_SIGNAL_ID_KEY).item(0).getTextContent(); + String cVal = String.valueOf(osBindingElement.getElementsByTagName(PnmlConstants.CURRENT_VALUE_KEY).item(0).getTextContent()); + + OutputSignalBinding osb = new OutputSignalBinding(); + parseOutputMappings(osBindingElement, pID, osID, cVal, osb); + jastAddBindingList.add(osb); + } + } + } + + return jastAddBindingList; + } + + private static void parseOutputMappings(Element osBindingElement, String pID, String osID, String cVal, OutputSignalBinding osb) { + //osb.setCurrentValue(cVal); + osb.setOutputSignalID(osID); + osb.setPlaceID(pID); + + NodeList eqMappingNodeList = osBindingElement.getElementsByTagName(PnmlConstants.EQUAL_OS_KEY); + NodeList thresholdMappingNodeList = osBindingElement.getElementsByTagName(PnmlConstants.TRESHOLD_KEY); + NodeList rangeMappingNodeList = osBindingElement.getElementsByTagName(PnmlConstants.RANGE_OS_KEY); + + for (int j = 0; j < eqMappingNodeList.getLength(); j++) { + Element eqElement = (Element) eqMappingNodeList.item(j); + EqualityOutputMapping eom = new EqualityOutputMapping(); + eom.setValue(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.VALUE_KEY).item(0).getTextContent())); + eom.setResult(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.RESULT_KEY).item(0).getTextContent())); + osb.addEqualityOM(eom); + } + + for (int k = 0; k < thresholdMappingNodeList.getLength(); k++) { + Element eqElement = (Element) thresholdMappingNodeList.item(k); + ThresholdOutputMapping tom = new ThresholdOutputMapping(); + tom.setValue(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.VALUE_KEY).item(0).getTextContent())); + tom.setResult(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.RESULT_KEY).item(0).getTextContent())); + osb.addThresholdOM(tom); + } + + for (int l = 0; l < rangeMappingNodeList.getLength(); l++) { + Element eqElement = (Element) rangeMappingNodeList.item(l); + RangeOutputMapping rom = new RangeOutputMapping(); + rom.setLowerBound(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.LOWER_BOUND_KEY).item(0).getTextContent())); + rom.setUpperBound(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.UPPER_BOUND_KEY).item(0).getTextContent())); + rom.setResult(Integer.valueOf(eqElement.getElementsByTagName(PnmlConstants.RESULT_KEY).item(0).getTextContent())); + osb.addRangeOM(rom); + } + } + + private static Document parseToolSpecifics(JastAddList<ToolInfo> toolInfos) throws ParserConfigurationException, SAXException, IOException { + + StringBuffer toolInfoStringBuffer = toolInfos.getChild(0).getFormattedXMLBuffer(); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + + Document doc = dBuilder.parse(fromStringBuffer(toolInfoStringBuffer)); + doc.getDocumentElement().normalize(); + + return doc; + } + + private static InputStream fromStringBuffer(StringBuffer buf) { + return new ByteArrayInputStream(buf.toString().getBytes()); + } + + /*public IoPetriNet doPostProcessing(PetriNet petriNet) { + + System.out.println("doPostProcessing called"); + + try { + IoPetriNet ioPetriNet = new IoPetriNet(); + ioPetriNet.setPN(petriNet); + + if (petriNet.getToolspecificList() != null && petriNet.getToolspecificList().getNumChild() > 0) { + + Document doc = parseToolSpecifics(petriNet.getToolspecificList()); + this.parseSignalDefinitions(doc, ioPetriNet); + this.parseInputSignalBindingDefinitions(doc, ioPetriNet); + this.parseOutputSignalBindingDefinitions(doc, ioPetriNet); + } + + return ioPetriNet; + + } catch (ParserConfigurationException | SAXException | IOException e) { + logger.error(e.getMessage()); + } + return null; + }/* + + + /*private void parseSignalDefinitions(Document doc, IoPetriNet ioPetriNet) { + + NodeList isDefList = doc.getElementsByTagName(PnmlConstants.INPUT_SIGNALS_KEY); + NodeList osDefList = doc.getElementsByTagName(PnmlConstants.OUTPUT_SIGNALS_KEY); + + ArrayList<String> inputSignalIds = new ArrayList<>(); + ArrayList<String> outputSignalIds = new ArrayList<>(); + + if (isDefList.getLength() > 0 && isDefList.item(0) != null) { + + Node nNode = isDefList.item(0); + + if (nNode.getNodeType() == Node.ELEMENT_NODE) { + + Element eElement = (Element) nNode; + + NodeList inputSignals = eElement.getElementsByTagName(PnmlConstants.INPUT_SIGNAL_KEY); + + for (int i = 0; i < inputSignals.getLength(); i++) { + inputSignalIds.add(inputSignals.item(i).getTextContent()); + } + } + } + + if (osDefList.getLength() > 0 && osDefList.item(0) != null) { + + Node nNode = osDefList.item(0); + + if (nNode.getNodeType() == Node.ELEMENT_NODE) { + + Element eElement = (Element) nNode; + + NodeList outputSignals = eElement.getElementsByTagName(PnmlConstants.OUTPUT_SIGNAL_KEY); + + for (int i = 0; i < outputSignals.getLength(); i++) { + outputSignalIds.add(outputSignals.item(i).getTextContent()); + } + } + } + + for (String isId : inputSignalIds) { + InputSignal is = new InputSignal(); + is.setID(isId); + ioPetriNet.addIS(is); + } + + for (String osId : outputSignalIds) { + OutputSignal os = new OutputSignal(); + os.setID(osId); + ioPetriNet.addOS(os); + } + }*/ +} \ No newline at end of file diff --git a/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessor.java b/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..a553ebef66f54b17b3c5a83ac15b1916f100bdab --- /dev/null +++ b/src/main/java/de/tudresden/inf/st/postprocessing/PostProcessor.java @@ -0,0 +1,5 @@ +package de.tudresden.inf.st.postprocessing; + +public interface PostProcessor<InputModelType> { + +} diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..38dc0735d33a8cf955e91f530b601f339aec709f --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration> + <Appenders> + <Console name="Console"> + <PatternLayout pattern="%highlight{%d{HH:mm:ss.SSS} %-5level} %c{1.} - %msg%n"/> + </Console> + <RollingFile name="RollingFile" fileName="logs/statemachine.log" + filePattern="logs/pnml-%i.log"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"/> + <Policies> + <OnStartupTriggeringPolicy/> + </Policies> + <DefaultRolloverStrategy max="20"/> + </RollingFile> + </Appenders> + <Loggers> + <Root level="info"> + <AppenderRef ref="Console"/> + <AppenderRef ref="RollingFile"/> + </Root> + </Loggers> +</Configuration> diff --git a/src/main/resources/minimal.pnml b/src/main/resources/minimal.pnml new file mode 100644 index 0000000000000000000000000000000000000000..ca40464368969be37dad3c871331227c1de11f07 --- /dev/null +++ b/src/main/resources/minimal.pnml @@ -0,0 +1,237 @@ +<pnml xmlns="http://www.pnml.org/version-2009/grammar/pnml"> + <net id="n-E2D0-BCF46-0" type ="http://www.pnml.org/version-2009/grammar/ptnet"> + <name> + <text>minimal</text> + </name> + <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1"> + </toolspecific> + <page id="g-E2D0-BCF68-1"> + <place id="p1"> + <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1"> + <location>node-1</location> + <type>discretePlaceType</type> + <outputsignalbindings> + <outputsignalbinding> + <placeID>p1</placeID> + <outputsignalID>os2</outputsignalID> + <initialvalue>1</initialvalue> <!-- -1 = undefined --> + <outputmappings> + <equal> + <value>1</value> + <result>3</result> + </equal> + <equal> + <value>0</value> + <result>2</result> + </equal> + <threshold> + <value>6</value> + <result>0</result> + </threshold> + <range> + <upperbound>5</upperbound> + <lowerbound>3</lowerbound> + <result>1</result> + </range> + </outputmappings> + </outputsignalbinding> + </outputsignalbindings> + </toolspecific> + <name> + <text>p1</text> + <graphics> + <offset x="0" y="-10" /> + </graphics> + </name> + <initialMarking> + <text>1</text> + </initialMarking> + <graphics> + <position x="30" y="50"/> + </graphics> + </place> + <place id="p2"> + <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1"> + <location>node-1</location> + <type>discretePlaceType</type> + <outputsignalbindings> + <outputsignalbinding> + <placeID>p2</placeID> + <outputsignalID>os1</outputsignalID> + <initialvalue>4</initialvalue> <!-- -1 = undefined --> + <outputmappings> + <equal> + <value>1</value> + <result>1</result> + </equal> + <threshold> + <value>6</value> + <result>0</result> + </threshold> + <range> + <upperbound>5</upperbound> + <lowerbound>3</lowerbound> + <result>1</result> + </range> + </outputmappings> + </outputsignalbinding> + </outputsignalbindings> + </toolspecific> + <name> + <text>p1</text> + <graphics> + <offset x="0" y="-10" /> + </graphics> + </name> + <initialMarking> + <text>1</text> + </initialMarking> + <graphics> + <position x="635" y="90"/> + </graphics> + </place> + <place id="p3"> + <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1"> + <location>node-1</location> + <type>discretePlaceType</type> + <outputsignalbindings> + <outputsignalbinding> + <placeID>p3</placeID> + <outputsignalID>os5</outputsignalID> + <initialvalue>4</initialvalue> <!-- -1 = undefined --> + <outputmappings> + <equal> + <value>1</value> + <result>1</result> + </equal> + <threshold> + <value>2</value> + <result>0</result> + </threshold> + </outputmappings> + </outputsignalbinding> + </outputsignalbindings> + </toolspecific> + <name> + <text>p3</text> + <graphics> + <offset x="0" y="-10" /> + </graphics> + </name> + <initialMarking> + <text>1</text> + </initialMarking> + <graphics> + <position x="635" y="90"/> + </graphics> + </place> + <transition id="t1"> + <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1"> + <location>node-1</location> + <type>discreteTransitionType</type> + <inputsignalbindings> + <inputsignalbinding> + <transitionID>t1</transitionID> + <inputsignalID>is1</inputsignalID> + <initialvalue>1</initialvalue> + </inputsignalbinding> + <inputsignalbinding> + <transitionID>t1</transitionID> + <inputsignalID>is3</inputsignalID> + <initialvalue>1</initialvalue> + </inputsignalbinding> + </inputsignalbindings> + </toolspecific> + <name> + <text>t0</text> + <graphics> + <offset x="0" y="0" /> + </graphics> + </name> + <graphics> + <position x="300" y="50"/> + </graphics> + </transition> + <transition id="t2"> + <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1"> + <location>node-1</location> + <type>discreteTransitionType</type> + <inputsignalbindings> + <inputsignalbinding> + <transitionID>t2</transitionID> + <inputsignalID>is2</inputsignalID> + <initialvalue>0</initialvalue> + </inputsignalbinding> + </inputsignalbindings> + </toolspecific> + <name> + <text>t1</text> + <graphics> + <offset x="0" y="0" /> + </graphics> + </name> + <graphics> + <position x="285" y="205"/> + </graphics> + </transition> + <transition id="t3"> + <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1"> + <location>node-1</location> + <type>unlimitedChannelOutType</type> + <topic>c1</topic> + <inputsignalbindings> + <inputsignalbinding> + <transitionID>t3</transitionID> + <inputsignalID>is3</inputsignalID> + <initialvalue>1</initialvalue> + </inputsignalbinding> + </inputsignalbindings> + </toolspecific> + <name> + <text>t3</text> + <graphics> + <offset x="0" y="0" /> + </graphics> + </name> + <graphics> + <position x="265" y="205"/> + </graphics> + </transition> + <transition id="t4"> + <toolspecific tool="de.tudresden.inf.st.pnml.distributedPN" version="0.0.1"> + <location>node-1</location> + <type>unlimitedChannelInType</type> + <topic>c1</topic> + <inputsignalbindings> + <inputsignalbinding> + <transitionID>t4</transitionID> + <inputsignalID>is4</inputsignalID> + <initialvalue>1</initialvalue> + </inputsignalbinding> + </inputsignalbindings> + </toolspecific> + <name> + <text>t4</text> + <graphics> + <offset x="0" y="0" /> + </graphics> + </name> + <graphics> + <position x="205" y="205"/> + </graphics> + </transition> + <arc id="arc-t2-p1" source="t2" target="p1"> + </arc> + <arc id="arc-p2-t2" source="p2" target="t2"> + </arc> + <arc id="arc-t1-p2" source="t1" target="p2"> + </arc> + <arc id="arc-p1-t1" source="p1" target="t1"> + </arc> + <arc id="arc-p1-t3" source="p1" target="t3"> + </arc> + <arc id="arc-t4-p3" source="t4" target="p3"> + </arc> + </page> + </net> +</pnml> \ No newline at end of file diff --git a/src/main/resources/placeTransition.ecore b/src/main/resources/placeTransition.ecore new file mode 100644 index 0000000000000000000000000000000000000000..f4c4351b6a8ef6e4751beae215ef9b8eddaa4c7a --- /dev/null +++ b/src/main/resources/placeTransition.ecore @@ -0,0 +1,336 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Meta-model for PNML specification --> +<!-- Provided by www.pnml.org --> +<ecore:EPackage xmi:version="2.0" + xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="ptnet" + nsURI="http:///ptnet.ecore" nsPrefix="ptnet"> + <eClassifiers xsi:type="ecore:EClass" name="PTMarking" eSuperTypes="#//Annotation"> + <eAnnotations source="http://www.pnml.org/models/OCL"> + <details key="markingValueRange" value="self.text >= 0"/> + </eAnnotations> + <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore"> + <details key="constraints" value="markingValueRange"/> + </eAnnotations> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" lowerBound="1" eType="#//Natural"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerPlace" eType="#//Place" + eOpposite="#//Place/initialMarking"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PTArcAnnotation" eSuperTypes="#//Annotation"> + <eAnnotations source="http://www.pnml.org/models/OCL"> + <details key="inscriptionValueRange" value="self.text > 0"/> + </eAnnotations> + <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore"> + <details key="constraints" value="inscriptionValueRange"/> + </eAnnotations> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" lowerBound="1" eType="#//PositiveInteger"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerArc" eType="#//Arc" + eOpposite="#//Arc/inscription"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EDataType" name="PositiveInteger" instanceClassName="java.lang.Integer"/> + <eClassifiers xsi:type="ecore:EDataType" name="Natural" instanceClassName="java.lang.Integer"/> + <eClassifiers xsi:type="ecore:EClass" name="PetriNetDoc"> + <eStructuralFeatures xsi:type="ecore:EReference" name="nets" ordered="false" lowerBound="1" + upperBound="-1" eType="#//PetriNet" containment="true" eOpposite="#//PetriNet/containerPetriNetDoc"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="xmlns" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" + changeable="false" defaultValueLiteral="http://www.pnml.org/version-2009/grammar/pnml"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PetriNet"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" ordered="false" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" defaultValueLiteral="" + iD="true"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" ordered="false" lowerBound="1" + eType="#//PNType" defaultValueLiteral=""/> + <eStructuralFeatures xsi:type="ecore:EReference" name="pages" ordered="false" + lowerBound="1" upperBound="-1" eType="#//Page" containment="true" eOpposite="#//Page/containerPetriNet"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="name" ordered="false" eType="#//Name" + containment="true" eOpposite="#//Name/containerNamePetriNet"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="toolspecifics" ordered="false" + upperBound="-1" eType="#//ToolInfo" containment="true" eOpposite="#//ToolInfo/containerPetriNet"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerPetriNetDoc" ordered="false" + eType="#//PetriNetDoc" eOpposite="#//PetriNetDoc/nets"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="PNType"> + <eLiterals name="PTNET" value="1" literal="http://www.pnml.org/version-2009/grammar/ptnet"/> + <eLiterals name="COREMODEL" literal="http://www.pnml.org/version-2009/grammar/pnmlcoremodel"/> + <eLiterals name="SYMNET" value="2" literal="http://www.pnml.org/version-2009/grammar/snnet"/> + <eLiterals name="HLPN" value="3" literal="http://www.pnml.org/version-2009/grammar/highlevelnet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Page" eSuperTypes="#//PnObject"> + <eStructuralFeatures xsi:type="ecore:EReference" name="objects" ordered="false" + upperBound="-1" eType="#//PnObject" containment="true" eOpposite="#//PnObject/containerPage"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerPetriNet" ordered="false" + eType="#//PetriNet" eOpposite="#//PetriNet/pages"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodegraphics" eType="#//NodeGraphics" + containment="true" eOpposite="#//NodeGraphics/containerPage"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PnObject" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" ordered="false" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" iD="true"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="name" ordered="false" eType="#//Name" + containment="true" eOpposite="#//Name/containerNamePnObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="toolspecifics" ordered="false" + upperBound="-1" eType="#//ToolInfo" containment="true" eOpposite="#//ToolInfo/containerPnObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerPage" ordered="false" + eType="#//Page" eOpposite="#//Page/objects"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Name" eSuperTypes="#//Annotation"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="text" ordered="false" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerNamePetriNet" + eType="#//PetriNet" eOpposite="#//PetriNet/name"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerNamePnObject" + eType="#//PnObject" eOpposite="#//PnObject/name"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ToolInfo"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="tool" ordered="false" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" ordered="false" + lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="formattedXMLBuffer" ordered="false" + eType="#//LongString"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="toolInfoGrammarURI" ordered="false" + eType="#//URI"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerPetriNet" ordered="false" + eType="#//PetriNet" eOpposite="#//PetriNet/toolspecifics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerPnObject" ordered="false" + eType="#//PnObject" eOpposite="#//PnObject/toolspecifics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerLabel" ordered="false" + eType="#//Label" eOpposite="#//Label/toolspecifics"/> +<!-- <eStructuralFeatures xsi:type="ecore:EReference" name="toolInfoModel" eType="#//AnyObject"--> +<!-- containment="true" eOpposite="#//AnyObject/containerToolInfo"/>--> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Label" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EReference" name="toolspecifics" ordered="false" + upperBound="-1" eType="#//ToolInfo" containment="true" eOpposite="#//ToolInfo/containerLabel"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="NodeGraphics" eSuperTypes="#//Graphics"> + <eStructuralFeatures xsi:type="ecore:EReference" name="position" ordered="false" + eType="#//Position" containment="true" eOpposite="#//Position/containerPNodeGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="dimension" ordered="false" + eType="#//Dimension" containment="true" eOpposite="#//Dimension/containerDNodeGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="fill" ordered="false" eType="#//Fill" + containment="true" eOpposite="#//Fill/containerNodeGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="line" ordered="false" eType="#//Line" + containment="true" eOpposite="#//Line/containerNodeGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerNode" eType="#//Node" + eOpposite="#//Node/nodegraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerPage" eType="#//Page" + eOpposite="#//Page/nodegraphics"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Graphics" abstract="true"/> + <eClassifiers xsi:type="ecore:EClass" name="Coordinate" abstract="true"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="x" ordered="false" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="y" ordered="false" lowerBound="1" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Position" eSuperTypes="#//Coordinate"> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerArcGraphics" ordered="false" + eType="#//ArcGraphics" eOpposite="#//ArcGraphics/positions"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerPNodeGraphics" + eType="#//NodeGraphics" eOpposite="#//NodeGraphics/position"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Offset" eSuperTypes="#//Coordinate"> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotationGraphics" + ordered="false" eType="#//AnnotationGraphics" eOpposite="#//AnnotationGraphics/offset"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Dimension" eSuperTypes="#//Coordinate"> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerDNodeGraphics" + ordered="false" eType="#//NodeGraphics" eOpposite="#//NodeGraphics/dimension"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="AnnotationGraphics" eSuperTypes="#//Graphics"> + <eStructuralFeatures xsi:type="ecore:EReference" name="offset" ordered="false" + eType="#//Offset" containment="true" eOpposite="#//Offset/containerAnnotationGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="fill" ordered="false" eType="#//Fill" + containment="true" eOpposite="#//Fill/containerAnnotationGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="line" ordered="false" eType="#//Line" + containment="true" eOpposite="#//Line/containerAnnotationGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="font" ordered="false" eType="#//Font" + containment="true" eOpposite="#//Font/containerAnnotationGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotation" eType="#//Annotation" + eOpposite="#//Annotation/annotationgraphics"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Fill"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="color" ordered="false" + eType="#//CSS2Color" defaultValueLiteral="BLACK"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="gradientcolor" ordered="false" + eType="#//CSS2Color" defaultValueLiteral="BLACK"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="gradientrotation" ordered="false" + eType="#//Gradient"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="image" ordered="false" + eType="#//URI"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerNodeGraphics" + ordered="false" eType="#//NodeGraphics" eOpposite="#//NodeGraphics/fill"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotationGraphics" + ordered="false" eType="#//AnnotationGraphics" eOpposite="#//AnnotationGraphics/fill"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="CSS2Color"> + <eLiterals name="AQUA" literal="aqua"/> + <eLiterals name="BLACK" value="1" literal="black"/> + <eLiterals name="BLUE" value="2" literal="blue"/> + <eLiterals name="FUCHSIA" value="3" literal="fuchsia"/> + <eLiterals name="GRAY" value="4" literal="gray"/> + <eLiterals name="GREEN" value="5" literal="green"/> + <eLiterals name="LIME" value="6" literal="lime"/> + <eLiterals name="MAROON" value="7" literal="maroon"/> + <eLiterals name="NAVY" value="8" literal="navy"/> + <eLiterals name="OLIVE" value="9" literal="olive"/> + <eLiterals name="ORANGE" value="10" literal="orange"/> + <eLiterals name="PURPLE" value="11" literal="purple"/> + <eLiterals name="RED" value="12" literal="red"/> + <eLiterals name="SILVER" value="13" literal="silver"/> + <eLiterals name="TEAL" value="14" literal="teal"/> + <eLiterals name="WHITE" value="15" literal="white"/> + <eLiterals name="YELLOW" value="16" literal="yellow"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="Gradient"> + <eLiterals name="HORIZONTAL" literal="horizontal"/> + <eLiterals name="VERTICAL" value="1" literal="vertical"/> + <eLiterals name="DIAGONAL" value="2" literal="diagonal"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Line"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="color" ordered="false" + eType="#//CSS2Color" defaultValueLiteral="BLACK"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="shape" ordered="false" + eType="#//LineShape" defaultValueLiteral="LINE"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="width" ordered="false" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerNodeGraphics" + ordered="false" eType="#//NodeGraphics" eOpposite="#//NodeGraphics/line"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerArcGraphics" ordered="false" + eType="#//ArcGraphics" eOpposite="#//ArcGraphics/line"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotationGraphics" + ordered="false" eType="#//AnnotationGraphics" eOpposite="#//AnnotationGraphics/line"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="style" eType="#//LineStyle"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="LineShape"> + <eLiterals name="LINE" literal="line"/> + <eLiterals name="CURVE" value="1" literal="curve"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="ArcGraphics" eSuperTypes="#//Graphics"> + <eStructuralFeatures xsi:type="ecore:EReference" name="positions" upperBound="-1" + eType="#//Position" containment="true" eOpposite="#//Position/containerArcGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="line" ordered="false" eType="#//Line" + containment="true" eOpposite="#//Line/containerArcGraphics"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerArc" eType="#//Arc" + eOpposite="#//Arc/arcgraphics"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Arc" eSuperTypes="#//PnObject"> + <eAnnotations source="http://www.pnml.org/models/OCL"> + <details key="samePageSourceTarget" value="self.source.containerPage = self.target.containerPage"/> + <details key="differentSourceTarget" value="(self.source.oclIsKindOf(PlaceNode) and self.target.oclIsKindOf(TransitionNode)) or (self.source.oclIsKindOf(TransitionNode) and self.target.oclIsKindOf(PlaceNode))"/> + </eAnnotations> + <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore"> + <details key="constraints" value="samePageSourceTarget differentSourceTarget"/> + </eAnnotations> + <eStructuralFeatures xsi:type="ecore:EReference" name="source" ordered="false" + lowerBound="1" eType="#//Node" eOpposite="#//Node/OutArcs"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="target" ordered="false" + lowerBound="1" eType="#//Node" eOpposite="#//Node/InArcs"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="arcgraphics" ordered="false" + eType="#//ArcGraphics" containment="true" eOpposite="#//ArcGraphics/containerArc"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="inscription" eType="#//PTArcAnnotation" + containment="true" eOpposite="#//PTArcAnnotation/containerArc"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Node" abstract="true" eSuperTypes="#//PnObject"> + <eStructuralFeatures xsi:type="ecore:EReference" name="InArcs" ordered="false" + upperBound="-1" eType="#//Arc" changeable="false" eOpposite="#//Arc/target"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="OutArcs" ordered="false" + upperBound="-1" eType="#//Arc" changeable="false" eOpposite="#//Arc/source"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="nodegraphics" eType="#//NodeGraphics" + containment="true" eOpposite="#//NodeGraphics/containerNode"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Font"> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="align" ordered="false" + eType="#//FontAlign" defaultValueLiteral="LEFT"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="decoration" ordered="false" + eType="#//FontDecoration" defaultValueLiteral="UNDERLINE"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="family" ordered="false" + eType="#//CSS2FontFamily" defaultValueLiteral="VERDANA"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="rotation" ordered="false" + eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBigDecimal"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="size" ordered="false" eType="#//CSS2FontSize" + defaultValueLiteral="SMALL"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="style" ordered="false" + eType="#//CSS2FontStyle" defaultValueLiteral="NORMAL"/> + <eStructuralFeatures xsi:type="ecore:EAttribute" name="weight" ordered="false" + eType="#//CSS2FontWeight"/> + <eStructuralFeatures xsi:type="ecore:EReference" name="containerAnnotationGraphics" + ordered="false" eType="#//AnnotationGraphics" eOpposite="#//AnnotationGraphics/font"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="FontAlign"> + <eLiterals name="LEFT" literal="left"/> + <eLiterals name="CENTER" value="1" literal="center"/> + <eLiterals name="RIGHT" value="2" literal="right"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="FontDecoration"> + <eLiterals name="UNDERLINE" literal="underline"/> + <eLiterals name="OVERLINE" value="1" literal="overline"/> + <eLiterals name="LINETHROUGH" value="2" literal="linethrough"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="CSS2FontFamily"> + <eLiterals name="VERDANA" literal="verdana"/> + <eLiterals name="ARIAL" value="1" literal="arial"/> + <eLiterals name="TIMES" value="2" literal="times"/> + <eLiterals name="GEORGIA" value="3" literal="georgia"/> + <eLiterals name="TREBUCHET" value="4" literal="trebuchet"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="CSS2FontSize"> + <eLiterals name="XXSMALL" literal="xxsmall"/> + <eLiterals name="XSMALL" value="1" literal="xsmall"/> + <eLiterals name="SMALL" value="2" literal="small"/> + <eLiterals name="MEDIUM" value="3" literal="medium"/> + <eLiterals name="LARGE" value="4" literal="large"/> + <eLiterals name="XLARGE" value="5" literal="xlarge"/> + <eLiterals name="XXLARGE" value="6" literal="xxlarge"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="CSS2FontStyle"> + <eLiterals name="NORMAL" literal="normal"/> + <eLiterals name="ITALIC" value="1" literal="italic"/> + <eLiterals name="OBLIQUE" value="2" literal="oblique"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EEnum" name="CSS2FontWeight"> + <eLiterals name="NORMAL" literal="normal"/> + <eLiterals name="BOLD" value="1" literal="bold"/> + <eLiterals name="BOLDER" value="2" literal="bolder"/> + <eLiterals name="LIGHTER" value="3" literal="lighter"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="PlaceNode" abstract="true" eSuperTypes="#//Node"> + <eStructuralFeatures xsi:type="ecore:EReference" name="referencingPlaces" upperBound="-1" + eType="#//RefPlace" changeable="false" eOpposite="#//RefPlace/ref"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="TransitionNode" abstract="true" eSuperTypes="#//Node"> + <eStructuralFeatures xsi:type="ecore:EReference" name="referencingTransitions" + upperBound="-1" eType="#//RefTransition" changeable="false" eOpposite="#//RefTransition/ref"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Place" eSuperTypes="#//PlaceNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="initialMarking" eType="#//PTMarking" + containment="true" eOpposite="#//PTMarking/containerPlace"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="RefTransition" eSuperTypes="#//TransitionNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="ref" ordered="false" lowerBound="1" + eType="#//TransitionNode" eOpposite="#//TransitionNode/referencingTransitions"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Transition" eSuperTypes="#//TransitionNode"/> + <eClassifiers xsi:type="ecore:EClass" name="RefPlace" eSuperTypes="#//PlaceNode"> + <eStructuralFeatures xsi:type="ecore:EReference" name="ref" ordered="false" lowerBound="1" + eType="#//PlaceNode" eOpposite="#//PlaceNode/referencingPlaces"/> + </eClassifiers> +<!-- <eClassifiers xsi:type="ecore:EClass" name="Attribute" abstract="true" eSuperTypes="#//Label"/>--> + <eClassifiers xsi:type="ecore:EEnum" name="LineStyle"> + <eLiterals name="SOLID" literal="solid"/> + <eLiterals name="DASH" value="1" literal="dash"/> + <eLiterals name="DOT" value="2" literal="dot"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="Annotation" abstract="true" eSuperTypes="#//Label"> + <eStructuralFeatures xsi:type="ecore:EReference" name="annotationgraphics" ordered="false" + eType="#//AnnotationGraphics" containment="true" eOpposite="#//AnnotationGraphics/containerAnnotation"/> + </eClassifiers> + <eClassifiers xsi:type="ecore:EDataType" name="URI" instanceClassName="java.net.URI"/> + <eClassifiers xsi:type="ecore:EDataType" name="LongString" instanceClassName="java.lang.StringBuffer"/> +<!-- <eClassifiers xsi:type="ecore:EClass" name="AnyObject" abstract="true">--> +<!-- <eStructuralFeatures xsi:type="ecore:EReference" name="containerToolInfo" eType="#//ToolInfo"--> +<!-- changeable="false" eOpposite="#//ToolInfo/toolInfoModel"/>--> +<!-- </eClassifiers>--> +</ecore:EPackage>