aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar OszkarSemerath <semerath@mit.bme.hu>2021-09-20 15:53:41 +0200
committerLibravatar OszkarSemerath <semerath@mit.bme.hu>2021-09-20 15:53:41 +0200
commit50de7f7e60540e7dd157aa83dffec0da9c5ca608 (patch)
tree69f0ce98be0b3c32fc324c95489cc540ec95a9e6
parentData structure for predicate representation (diff)
parentForce LF line endings in frontend files (diff)
downloadVIATRA-Generator-50de7f7e60540e7dd157aa83dffec0da9c5ca608.tar.gz
VIATRA-Generator-50de7f7e60540e7dd157aa83dffec0da9c5ca608.tar.zst
VIATRA-Generator-50de7f7e60540e7dd157aa83dffec0da9c5ca608.zip
Merge branch 'web-demo' of https://github.com/viatra/VIATRA-Generator.git into web-demo
-rw-r--r--.gitattributes7
-rw-r--r--language-model/build.gradle6
-rw-r--r--language-web/build.gradle24
-rw-r--r--language-web/src/main/css/index.scss5
-rw-r--r--language-web/src/main/css/themes.scss16
-rw-r--r--language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java2
-rw-r--r--language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java141
-rw-r--r--language-web/src/main/js/theme/EditorTheme.ts4
-rw-r--r--language-web/src/main/js/theme/ThemeStore.ts6
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe23
10 files changed, 141 insertions, 73 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..63f6b190
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,7 @@
1*.css eol=lf
2*.js eol=lf
3*.json eol=lf
4*.jsx eol=lf
5*.scss eol=lf
6*.ts eol=lf
7*.tsx eol=lf
diff --git a/language-model/build.gradle b/language-model/build.gradle
index 2d9b54b9..3950140c 100644
--- a/language-model/build.gradle
+++ b/language-model/build.gradle
@@ -31,4 +31,8 @@ task generateEPackage(type: JavaExec) {
31compileJava.dependsOn(generateEPackage) 31compileJava.dependsOn(generateEPackage)
32clean.dependsOn(cleanGenerateEPackage) 32clean.dependsOn(cleanGenerateEPackage)
33 33
34eclipse.project.natures += ['org.eclipse.sirius.nature.modelingproject', 'org.eclipse.pde.PluginNature'] 34eclipse.project.natures += [
35 'org.eclipse.sirius.nature.modelingproject',
36 'org.eclipse.pde.PluginNature',
37 'org.eclipse.xtext.ui.shared.xtextNature'
38]
diff --git a/language-web/build.gradle b/language-web/build.gradle
index a2acb3b0..6910fea0 100644
--- a/language-web/build.gradle
+++ b/language-web/build.gradle
@@ -7,15 +7,13 @@ dependencies {
7 compile "org.eclipse.xtext:org.eclipse.xtext.web.servlet:${xtextVersion}" 7 compile "org.eclipse.xtext:org.eclipse.xtext.web.servlet:${xtextVersion}"
8 compile "org.eclipse.xtend:org.eclipse.xtend.lib:${xtextVersion}" 8 compile "org.eclipse.xtend:org.eclipse.xtend.lib:${xtextVersion}"
9 compile "org.eclipse.jetty:jetty-server:${jettyVersion}" 9 compile "org.eclipse.jetty:jetty-server:${jettyVersion}"
10 compile "org.eclipse.jetty:jetty-annotations:${jettyVersion}" 10 compile "org.eclipse.jetty:jetty-servlet:${jettyVersion}"
11 compile "org.slf4j:slf4j-simple:${slf4JVersion}" 11 compile "org.slf4j:slf4j-simple:${slf4JVersion}"
12} 12}
13 13
14def webpackOutputDir = "${buildDir}/webpack" 14def webpackOutputDir = "${buildDir}/webpack"
15def productionResources = "${webpackOutputDir}/production" 15def productionResources = "${webpackOutputDir}/production"
16def mainClass = 'org.eclipse.viatra.solver.language.web.ServerLauncher' 16def mainClass = 'org.eclipse.viatra.solver.language.web.ServerLauncher'
17def devMode = System.getenv('NODE_ENV') != 'production'
18def currentNodeEnv = devMode ? 'development' : 'production'
19 17
20apply plugin: 'com.moowork.node' 18apply plugin: 'com.moowork.node'
21 19
@@ -71,18 +69,21 @@ shadowJar {
71} 69}
72 70
73task jettyRun(type: JavaExec) { 71task jettyRun(type: JavaExec) {
74 if (devMode) { 72 shouldRunAfter webpackProduction
75 dependsOn webpackDevelopment
76 } else {
77 dependsOn webpackProduction
78 }
79 dependsOn sourceSets.main.runtimeClasspath 73 dependsOn sourceSets.main.runtimeClasspath
80 classpath = sourceSets.main.runtimeClasspath.filter{it.exists()} 74 classpath = sourceSets.main.runtimeClasspath.filter{it.exists()}
81 main = mainClass 75 main = mainClass
82 standardInput = System.in 76 standardInput = System.in
83 environment BASE_RESOURCE: "${webpackOutputDir}/${currentNodeEnv}" 77 environment BASE_RESOURCE: productionResources
78 group = 'run'
79 description = 'Start a Jetty web server serving the Xtex API and assets (without rebuilding assets).'
80}
81
82task jettyRunAssets {
83 dependsOn webpackProduction
84 dependsOn jettyRun
84 group = 'run' 85 group = 'run'
85 description = 'Start a Jetty web server serving the Xtex API and assets.' 86 description = 'Rebuild assets and start a Jetty web server serving the Xtex API and assets.'
86} 87}
87 88
88task webpackServe(type: NpmTask) { 89task webpackServe(type: NpmTask) {
@@ -98,6 +99,9 @@ task webpackServe(type: NpmTask) {
98task eslint(type: NpmTask) { 99task eslint(type: NpmTask) {
99 dependsOn npmInstall 100 dependsOn npmInstall
100 args = ['run', 'eslint'] 101 args = ['run', 'eslint']
102 inputs.dir 'src/main/js'
103 inputs.file 'tsconfig.json'
104 inputs.file '.eslintrc.js'
101 group = 'verification' 105 group = 'verification'
102 description = 'Checks for TypeScript errors.' 106 description = 'Checks for TypeScript errors.'
103} 107}
diff --git a/language-web/src/main/css/index.scss b/language-web/src/main/css/index.scss
index 21a9c05b..9d6e0f6a 100644
--- a/language-web/src/main/css/index.scss
+++ b/language-web/src/main/css/index.scss
@@ -94,6 +94,11 @@ body {
94 color: map.get($theme, 'delimiter'); 94 color: map.get($theme, 'delimiter');
95 } 95 }
96 96
97 .cm-comment {
98 color: map.get($theme, 'comment');
99 font-style: italic;
100 }
101
97 .problem-predicate, .problem-class, .problem-reference, .problem-enum { 102 .problem-predicate, .problem-class, .problem-reference, .problem-enum {
98 color: map.get($theme, 'predicate'); 103 color: map.get($theme, 'predicate');
99 } 104 }
diff --git a/language-web/src/main/css/themes.scss b/language-web/src/main/css/themes.scss
index 0118290d..a30f1de3 100644
--- a/language-web/src/main/css/themes.scss
+++ b/language-web/src/main/css/themes.scss
@@ -1,8 +1,8 @@
1$themes: ( 1$themes: (
2 'dark': ( 2 'dark': (
3 'foreground': #abb2bf, 3 'foreground': #abb2bf,
4 'background': #282c34, 4 'foregroundHighlight': #eeffff,
5 'paper': #21252b, 5 'background': #212121,
6 'primary': #56b6c2, 6 'primary': #56b6c2,
7 'secondary': #ff5370, 7 'secondary': #ff5370,
8 'keyword': #56b6c2, 8 'keyword': #56b6c2,
@@ -10,11 +10,12 @@ $themes: (
10 'variable': #c8ae9d, 10 'variable': #c8ae9d,
11 'uniqueNode': #d6e9ff, 11 'uniqueNode': #d6e9ff,
12 'number': #6e88a6, 12 'number': #6e88a6,
13 'delimiter': #6f7682, 13 'delimiter': #707787,
14 'comment': #5c6370,
14 'cursor': #56b6c2, 15 'cursor': #56b6c2,
15 'selection': #3e4452, 16 'selection': #3e4452,
16 'currentLine': #2c323c, 17 'currentLine': rgba(0, 0, 0, 0.2),
17 'lineNumber': #5c6340, 18 'lineNumber': #5c6370,
18 ), 19 ),
19 'light': ( 20 'light': (
20 'foreground': #abb2bf, 21 'foreground': #abb2bf,
@@ -27,10 +28,11 @@ $themes: (
27 'variable': #c8ae9d, 28 'variable': #c8ae9d,
28 'uniqueNode': #d6e9ff, 29 'uniqueNode': #d6e9ff,
29 'number': #6e88a6, 30 'number': #6e88a6,
30 'delimiter': #6f7682, 31 'delimiter': #56606d,
32 'comment': #55606d,
31 'cursor': #f3efe7, 33 'cursor': #f3efe7,
32 'selection': #3e4452, 34 'selection': #3e4452,
33 'currentLine': #2c323c, 35 'currentLine': #2c323c,
34 'lineNumber': #5c6340, 36 'lineNumber': #5c6370,
35 ), 37 ),
36); 38);
diff --git a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java
index 337df54b..18b86ade 100644
--- a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java
+++ b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ProblemServlet.java
@@ -4,7 +4,6 @@
4package org.eclipse.viatra.solver.language.web; 4package org.eclipse.viatra.solver.language.web;
5 5
6import javax.servlet.ServletException; 6import javax.servlet.ServletException;
7import javax.servlet.annotation.WebServlet;
8 7
9import org.eclipse.xtext.util.DisposableRegistry; 8import org.eclipse.xtext.util.DisposableRegistry;
10import org.eclipse.xtext.web.servlet.XtextServlet; 9import org.eclipse.xtext.web.servlet.XtextServlet;
@@ -12,7 +11,6 @@ import org.eclipse.xtext.web.servlet.XtextServlet;
12/** 11/**
13 * Deploy this class into a servlet container to enable DSL-specific services. 12 * Deploy this class into a servlet container to enable DSL-specific services.
14 */ 13 */
15@WebServlet(name = "XtextServices", urlPatterns = "/xtext-service/*")
16public class ProblemServlet extends XtextServlet { 14public class ProblemServlet extends XtextServlet {
17 15
18 private static final long serialVersionUID = 1L; 16 private static final long serialVersionUID = 1L;
diff --git a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java
index 2c0413df..d92c7735 100644
--- a/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java
+++ b/language-web/src/main/java/org/eclipse/viatra/solver/language/web/ServerLauncher.java
@@ -3,37 +3,67 @@
3 */ 3 */
4package org.eclipse.viatra.solver.language.web; 4package org.eclipse.viatra.solver.language.web;
5 5
6import java.io.File;
6import java.io.IOException; 7import java.io.IOException;
7import java.net.InetSocketAddress; 8import java.net.InetSocketAddress;
8import java.net.URI; 9import java.net.URI;
9import java.net.URISyntaxException; 10import java.net.URISyntaxException;
11import java.util.Set;
12
13import javax.servlet.SessionTrackingMode;
10 14
11import org.eclipse.jetty.annotations.AnnotationConfiguration;
12import org.eclipse.jetty.server.Server; 15import org.eclipse.jetty.server.Server;
16import org.eclipse.jetty.server.session.SessionHandler;
17import org.eclipse.jetty.servlet.DefaultServlet;
18import org.eclipse.jetty.servlet.ServletContextHandler;
19import org.eclipse.jetty.servlet.ServletHolder;
13import org.eclipse.jetty.util.log.Slf4jLog; 20import org.eclipse.jetty.util.log.Slf4jLog;
14import org.eclipse.jetty.util.resource.Resource; 21import org.eclipse.jetty.util.resource.Resource;
15import org.eclipse.jetty.webapp.Configuration;
16import org.eclipse.jetty.webapp.MetaInfConfiguration;
17import org.eclipse.jetty.webapp.WebAppContext;
18import org.eclipse.jetty.webapp.WebInfConfiguration;
19import org.eclipse.jetty.webapp.WebXmlConfiguration;
20 22
21public class ServerLauncher { 23public class ServerLauncher {
24 public static final String DEFAULT_LISTEN_ADDRESS = "localhost";
25
26 public static final int DEFAULT_LISTEN_PORT = 1312;
27
28 // Use this cookie name for load balancing.
29 public static final String SESSION_COOKIE_NAME = "JSESSIONID";
30
22 private static final Slf4jLog LOG = new Slf4jLog(ServerLauncher.class.getName()); 31 private static final Slf4jLog LOG = new Slf4jLog(ServerLauncher.class.getName());
23 32
24 private final Server server; 33 private final Server server;
25 34
26 public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource) { 35 public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource) {
27 server = new Server(bindAddress); 36 server = new Server(bindAddress);
28 var ctx = new WebAppContext(); 37 var handler = new ServletContextHandler();
29 ctx.setBaseResource(baseResource); 38 addSessionHandler(handler);
30 ctx.setWelcomeFiles(new String[] { "index.html" }); 39 addProblemServlet(handler);
31 ctx.setContextPath("/"); 40 if (baseResource != null) {
32 ctx.setConfigurations(new Configuration[] { new AnnotationConfiguration(), new WebXmlConfiguration(), 41 handler.setBaseResource(baseResource);
33 new WebInfConfiguration(), new MetaInfConfiguration() }); 42 handler.setWelcomeFiles(new String[] { "index.html" });
34 ctx.setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, ".*/build/classes/.*,.*\\.jar"); 43 addDefaultServlet(handler);
35 ctx.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false"); 44 }
36 server.setHandler(ctx); 45 server.setHandler(handler);
46 }
47
48 private void addSessionHandler(ServletContextHandler handler) {
49 var sessionHandler = new SessionHandler();
50 sessionHandler.setSessionTrackingModes(Set.of(SessionTrackingMode.COOKIE));
51 sessionHandler.setSessionCookie(SESSION_COOKIE_NAME);
52 handler.setSessionHandler(sessionHandler);
53 }
54
55 private void addProblemServlet(ServletContextHandler handler) {
56 handler.addServlet(ProblemServlet.class, "/xtext-service/*");
57 }
58
59 private void addDefaultServlet(ServletContextHandler handler) {
60 var defaultServletHolder = new ServletHolder(DefaultServlet.class);
61 var isWindows = System.getProperty("os.name").toLowerCase().contains("win");
62 // Avoid file locking on Windows: https://stackoverflow.com/a/4985717
63 // See also the related Jetty ticket:
64 // https://github.com/eclipse/jetty.project/issues/2925
65 defaultServletHolder.setInitParameter("useFileMappedBuffer", isWindows ? "false" : "true");
66 handler.addServlet(defaultServletHolder, "/");
37 } 67 }
38 68
39 public void start() throws Exception { 69 public void start() throws Exception {
@@ -44,54 +74,65 @@ public class ServerLauncher {
44 if (key != -1) { 74 if (key != -1) {
45 server.stop(); 75 server.stop();
46 } else { 76 } else {
47 LOG.warn( 77 LOG.warn("Console input is not available. "
48 "Console input is not available. In order to stop the server, you need to cancel process manually."); 78 + "In order to stop the server, you need to cancel process manually.");
49 } 79 }
50 } 80 }
51 81
52 private static InetSocketAddress getBindAddress(String listenAddress, int port) { 82 public static void main(String[] args) {
53 if (listenAddress == null) { 83 try {
54 return new InetSocketAddress(port); 84 var bindAddress = getBindAddress();
55 } 85 var baseResource = getBaseResource();
56 return new InetSocketAddress(listenAddress, port); 86 var serverLauncher = new ServerLauncher(bindAddress, baseResource);
57 } 87 serverLauncher.start();
58 88 } catch (Exception exception) {
59 private static Resource getBaseResource(String baseResourceOverride) throws IOException, URISyntaxException { 89 LOG.warn(exception);
60 if (baseResourceOverride != null) { 90 System.exit(1);
61 return Resource.newResource(baseResourceOverride);
62 }
63 var indexUrlInJar = ServerLauncher.class.getResource("/webapp/index.html");
64 if (indexUrlInJar == null) {
65 throw new IOException("Cannot find pacakged web assets");
66 } 91 }
67 var webRootUri = URI.create(indexUrlInJar.toURI().toASCIIString().replaceFirst("/index.html$", "/"));
68 return Resource.newResource(webRootUri);
69 } 92 }
70 93
71 public static void main(String[] args) { 94 private static String getListenAddress() {
72 var listenAddress = System.getenv("LISTEN_ADDRESS"); 95 var listenAddress = System.getenv("LISTEN_ADDRESS");
73 if (listenAddress == null) { 96 if (listenAddress == null) {
74 listenAddress = "localhost"; 97 return DEFAULT_LISTEN_ADDRESS;
75 } 98 }
76 var port = 1312; 99 return listenAddress;
100 }
101
102 private static int getListenPort() {
77 var portStr = System.getenv("LISTEN_PORT"); 103 var portStr = System.getenv("LISTEN_PORT");
78 if (portStr != null) { 104 if (portStr != null) {
79 try { 105 return Integer.parseInt(portStr);
80 port = Integer.parseInt(portStr);
81 } catch (NumberFormatException e) {
82 LOG.warn(e);
83 System.exit(1);
84 }
85 } 106 }
107 return DEFAULT_LISTEN_PORT;
108 }
109
110 private static InetSocketAddress getBindAddress() {
111 var listenAddress = getListenAddress();
112 var listenPort = getListenPort();
113 return new InetSocketAddress(listenAddress, listenPort);
114 }
115
116 private static Resource getBaseResource() throws IOException, URISyntaxException {
86 var baseResourceOverride = System.getenv("BASE_RESOURCE"); 117 var baseResourceOverride = System.getenv("BASE_RESOURCE");
87 try { 118 if (baseResourceOverride != null) {
88 var bindAddress = getBindAddress(listenAddress, port); 119 // If a user override is provided, use it.
89 var baseResource = getBaseResource(baseResourceOverride); 120 return Resource.newResource(baseResourceOverride);
90 var serverLauncher = new ServerLauncher(bindAddress, baseResource); 121 }
91 serverLauncher.start(); 122 var indexUrlInJar = ServerLauncher.class.getResource("/webapp/index.html");
92 } catch (Exception exception) { 123 if (indexUrlInJar != null) {
93 LOG.warn(exception); 124 // If the app is packaged in the jar, serve it.
94 System.exit(1); 125 var webRootUri = URI.create(indexUrlInJar.toURI().toASCIIString().replaceFirst("/index.html$", "/"));
126 return Resource.newResource(webRootUri);
127 }
128 // Look for unpacked production artifacts (convenience for running from IDE).
129 var unpackedResourcePathComponents = new String[] { System.getProperty("user.dir"), "build", "webpack",
130 "production" };
131 var unpackedResourceDir = new File(String.join(File.separator, unpackedResourcePathComponents));
132 if (unpackedResourceDir.isDirectory()) {
133 return Resource.newResource(unpackedResourceDir);
95 } 134 }
135 // Fall back to just serving a 404.
136 return null;
96 } 137 }
97} 138}
diff --git a/language-web/src/main/js/theme/EditorTheme.ts b/language-web/src/main/js/theme/EditorTheme.ts
index 9420dafa..957f2426 100644
--- a/language-web/src/main/js/theme/EditorTheme.ts
+++ b/language-web/src/main/js/theme/EditorTheme.ts
@@ -16,9 +16,9 @@ export class EditorThemeData {
16 16
17 foreground!: string; 17 foreground!: string;
18 18
19 background!: string; 19 foregroundHighlight!: string;
20 20
21 paper!: string; 21 background!: string;
22 22
23 primary!: string; 23 primary!: string;
24 24
diff --git a/language-web/src/main/js/theme/ThemeStore.ts b/language-web/src/main/js/theme/ThemeStore.ts
index 0f283c98..0e4aeb23 100644
--- a/language-web/src/main/js/theme/ThemeStore.ts
+++ b/language-web/src/main/js/theme/ThemeStore.ts
@@ -34,7 +34,7 @@ export class ThemeStore {
34 mode: themeData.paletteMode, 34 mode: themeData.paletteMode,
35 background: { 35 background: {
36 default: themeData.background, 36 default: themeData.background,
37 paper: themeData.paper, 37 paper: themeData.background,
38 }, 38 },
39 primary: { 39 primary: {
40 main: themeData.primary, 40 main: themeData.primary,
@@ -42,6 +42,10 @@ export class ThemeStore {
42 secondary: { 42 secondary: {
43 main: themeData.secondary, 43 main: themeData.secondary,
44 }, 44 },
45 text: {
46 primary: themeData.foregroundHighlight,
47 secondary: themeData.foreground,
48 },
45 }, 49 },
46 }); 50 });
47 return responsiveFontSizes(materialUiTheme); 51 return responsiveFontSizes(materialUiTheme);
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2 b/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
index ca3e2665..9b0bcd41 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
@@ -53,6 +53,9 @@ Workflow {
53 webSupport = ProblemWebIntegrationFragment { 53 webSupport = ProblemWebIntegrationFragment {
54 highlightingPath = "js/mode-problem.js" 54 highlightingPath = "js/mode-problem.js"
55 generateHtmlExample = false 55 generateHtmlExample = false
56 generateJettyLauncher = false
57 generateServlet = false
58 generateWebXml = false
56 } 59 }
57 } 60 }
58 } 61 }