Jelajahi Sumber

New sgen builtin variables: SCTHASH and SCTFILE (#1944)

* Add new variables SHA256 & SCTFILE

* Add new variables to documentation
Rene Beckmann 7 tahun lalu
induk
melakukan
be866cfb01

+ 2 - 0
plugins/org.yakindu.sct.doc.user/src/user-guide/code_generation_intro.textile

@@ -337,6 +337,8 @@ There are several built-in read-only variables which can be used in expressions
 * _TIMESTAMP_ (String): the current date and time as a localized string, for example "11.12.2017 17:08:14"
 * _USER_ (String): the name of the current user who started this instance of YAKINDU Statechart Tools (via @System.getProperty("user.name")@)
 * _HOSTNAME_ (String): the host name of the machine on which YAKINDU Statechart Tools is running.
+* _SHA256_ (String): The hash of the referenced file (for example, the statechart file).
+* _SCTPATH_ (String): Path to the statechart file relative to the workspace.
 
 bq. *Please note:* Neither _USER_ nor _HOSTNAME_ should be used for any security-related tasks. Especially the username can be spoofed easily, if anyone wanted to.
 

+ 7 - 1
plugins/org.yakindu.sct.generator.genmodel/src/org/yakindu/sct/generator/genmodel/typesystem/BuiltinDeclarations.xtend

@@ -32,9 +32,11 @@ class BuiltinDeclarations implements BuiltinDeclarationNames {
 	protected ITypeSystem typeSystem
 
 	protected Property sct_version
+	protected Property sct_file
 	protected Property timestamp
 	protected Property hostname
 	protected Property username
+	protected Property sha256
 
 	protected Resource builtinResource
 
@@ -48,6 +50,8 @@ class BuiltinDeclarations implements BuiltinDeclarationNames {
 		timestamp = createProperty(TIMESTAMP_VAR, stringtype)
 		hostname = createProperty(HOSTNAME_VAR, stringtype)
 		username = createProperty(USER_VAR, stringtype)
+		sct_file = createProperty(SCTFILE, stringtype)
+		sha256 = createProperty(SHA256, stringtype)
 	}
 
 	def protected Property createProperty(String name, Type type) {
@@ -66,9 +70,11 @@ class BuiltinDeclarations implements BuiltinDeclarationNames {
 	def getDeclarations() {
 		#[
 			sct_version,
+			sct_file,
 			timestamp,
 			hostname,
-			username
+			username,
+			sha256
 		]
 	}
 

+ 3 - 1
plugins/org.yakindu.sct.model.sgen/META-INF/MANIFEST.MF

@@ -18,5 +18,7 @@ Require-Bundle: org.eclipse.core.runtime,
  org.yakindu.base.types,
  com.google.inject,
  org.yakindu.base.expressions,
- org.yakindu.base.expressions.interpreter
+ org.yakindu.base.expressions.interpreter,
+ org.eclipse.core.filesystem,
+ org.eclipse.core.resources
 Bundle-ActivationPolicy: lazy

+ 3 - 1
plugins/org.yakindu.sct.model.sgen/src/org/yakindu/sct/model/sgen/util/BuiltinDeclarationNames.java

@@ -6,7 +6,7 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * Contributors:
  * 	rbeckmann - initial API and implementation
- * 
+ *
  */
 package org.yakindu.sct.model.sgen.util;
 
@@ -16,6 +16,8 @@ package org.yakindu.sct.model.sgen.util;
  */
 public interface BuiltinDeclarationNames {
 	public static final String SCT_VERSION_VAR = "SCTVERSION";
+	public static final String SHA256 = "SHA256";
+	public static final String SCTFILE = "SCTFILE";
 	public static final String TIMESTAMP_VAR = "TIMESTAMP";
 	public static final String USER_VAR = "USER";
 	public static final String HOSTNAME_VAR = "HOSTNAME";

+ 58 - 0
plugins/org.yakindu.sct.model.sgen/src/org/yakindu/sct/model/sgen/util/BuiltinExpressionsInterpreter.xtend

@@ -9,13 +9,24 @@
  */
 package org.yakindu.sct.model.sgen.util
 
+import java.io.FileReader
 import java.net.InetAddress
+import java.nio.charset.StandardCharsets
+import java.nio.file.Files
+import java.nio.file.Paths
+import java.security.MessageDigest
 import java.text.DateFormat
 import java.util.Date
+import org.eclipse.core.resources.IFile
+import org.eclipse.core.resources.ResourcesPlugin
+import org.eclipse.emf.common.util.URI
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.EcoreUtil2
 import org.osgi.framework.FrameworkUtil
 import org.yakindu.base.expressions.expressions.ElementReferenceExpression
 import org.yakindu.base.expressions.interpreter.DefaultExpressionInterpreter
 import org.yakindu.base.types.Property
+import org.yakindu.sct.model.sgen.GeneratorEntry
 
 /** 
  * @author rbeckmann
@@ -38,6 +49,12 @@ class BuiltinExpressionsInterpreter extends DefaultExpressionInterpreter impleme
 				case HOSTNAME_VAR: {
 					return InetAddress.localHost.hostName.toString
 				}
+				case SHA256: {
+					return sha256(expression)
+				}
+				case SCTFILE: {
+					return sctfile(expression)
+				}
 				default:
 					return executeElementReferenceExpression(expression)
 			}
@@ -46,4 +63,45 @@ class BuiltinExpressionsInterpreter extends DefaultExpressionInterpreter impleme
 		executeElementReferenceExpression(expression)
 	}
 
+	def String sha256(ElementReferenceExpression expression) {
+		val uri = emfURI(expression)
+		val nioPath = Paths.get(uri.toFile.location.toOSString)
+		val content = Files.readAllBytes(nioPath)
+		val byte[] hash = MessageDigest.getInstance("SHA-256").digest(content);
+		bytesToHex(hash)
+	}
+	
+	def sctfile(ElementReferenceExpression expression) {
+		var path = emfURI(expression).toPlatformString(true)
+		if(path.startsWith("/")) {
+			path = path.substring(1)
+		}
+		path
+	}
+	
+	def emfURI(EObject eObject) {
+		val entry = EcoreUtil2.getContainerOfType(eObject, GeneratorEntry)
+		EcoreUtil2.getURI(entry.elementRef) 
+	}
+
+	def String bytesToHex(byte[] hash) {
+		val StringBuffer hexString = new StringBuffer();
+		for (var i = 0; i < hash.length; i++) {
+			var hex = Integer.toHexString(0xff.bitwiseAnd(hash.get(i)));
+			if (hex.length() == 1) {
+				hex = "0" + hex
+			}
+			hexString.append(hex);
+		}
+		return hexString.toString();
+	}
+
+	def IFile toFile(URI uri) {
+		if (uri.isPlatformResource()) {
+			val platformString = uri.toPlatformString(true)
+			return ResourcesPlugin.getWorkspace().getRoot().findMember(platformString) as IFile;
+		}
+		return null;
+	}
+
 }