aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-10-07 16:26:05 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-10-07 16:26:05 +0200
commit814295eecc10b7a87694b25c347d0821e3502c92 (patch)
tree96101ca9981cdbf518effc358c95357a4e9f3503
parentci(web): no typescript 4.4 features in Sonar (diff)
downloadrefinery-814295eecc10b7a87694b25c347d0821e3502c92.tar.gz
refinery-814295eecc10b7a87694b25c347d0821e3502c92.tar.zst
refinery-814295eecc10b7a87694b25c347d0821e3502c92.zip
chore(web): bump Jetty version
Requred vendoring org.eclipse.xtext.web.servlet as tools.refinery.language.web.xtext due to the javax -> jakarta package name change: https://www.eclipse.org/lists/jetty-announce/msg00149.html
-rw-r--r--gradle.properties4
-rw-r--r--language-web/build.gradle4
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java16
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/ProblemServlet.java22
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java24
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/HttpServiceContext.java107
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/HttpSessionWrapper.java53
-rw-r--r--language-web/src/main/java/tools/refinery/language/web/xtext/XtextServlet.java196
8 files changed, 387 insertions, 39 deletions
diff --git a/gradle.properties b/gradle.properties
index d0f99bd6..c4d174df 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,13 +1,13 @@
1ecoreVersion=2.25.0 1ecoreVersion=2.25.0
2ecoreCodegenVersion=2.27.0 2ecoreCodegenVersion=2.27.0
3hamcrestVersion=2.2 3hamcrestVersion=2.2
4jettyVersion=9.4.44.v20210927 4jettyVersion=11.0.6
5jmhVersion=1.32 5jmhVersion=1.32
6junitVersion=5.8.1 6junitVersion=5.8.1
7mweVersion=1.6.2.M1 7mweVersion=1.6.2.M1
8mwe2Version=2.12.2.M1 8mwe2Version=2.12.2.M1
9nodeVersion=14.18.0 9nodeVersion=14.18.0
10slf4JVersion=1.7.32 10slf4JVersion=2.0.0-alpha5
11viatraVersion=2.6.0 11viatraVersion=2.6.0
12xtextVersion=2.26.0.M2 12xtextVersion=2.26.0.M2
13xtextAntlrGeneratorVersion=2.1.1 13xtextAntlrGeneratorVersion=2.1.1
diff --git a/language-web/build.gradle b/language-web/build.gradle
index 15d743b9..c467c019 100644
--- a/language-web/build.gradle
+++ b/language-web/build.gradle
@@ -4,12 +4,12 @@ apply from: "${rootDir}/gradle/xtext-common.gradle"
4dependencies { 4dependencies {
5 implementation project(':refinery-language') 5 implementation project(':refinery-language')
6 implementation project(':refinery-language-ide') 6 implementation project(':refinery-language-ide')
7 implementation "org.eclipse.xtext:org.eclipse.xtext.xbase.web:${xtextVersion}" 7 implementation "org.eclipse.xtext:org.eclipse.xtext.web:${xtextVersion}"
8 implementation "org.eclipse.xtext:org.eclipse.xtext.web.servlet:${xtextVersion}"
9 implementation "org.eclipse.xtend:org.eclipse.xtend.lib:${xtextVersion}" 8 implementation "org.eclipse.xtend:org.eclipse.xtend.lib:${xtextVersion}"
10 implementation "org.eclipse.jetty:jetty-server:${jettyVersion}" 9 implementation "org.eclipse.jetty:jetty-server:${jettyVersion}"
11 implementation "org.eclipse.jetty:jetty-servlet:${jettyVersion}" 10 implementation "org.eclipse.jetty:jetty-servlet:${jettyVersion}"
12 implementation "org.slf4j:slf4j-simple:${slf4JVersion}" 11 implementation "org.slf4j:slf4j-simple:${slf4JVersion}"
12 implementation "org.slf4j:log4j-over-slf4j:${slf4JVersion}"
13} 13}
14 14
15def generateXtextLanguage = project(':refinery-language').tasks.named('generateXtextLanguage') 15def generateXtextLanguage = project(':refinery-language').tasks.named('generateXtextLanguage')
diff --git a/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java b/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
index e39ce54c..cf4c00fa 100644
--- a/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
+++ b/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
@@ -3,14 +3,14 @@ package tools.refinery.language.web;
3import java.io.IOException; 3import java.io.IOException;
4import java.util.regex.Pattern; 4import java.util.regex.Pattern;
5 5
6import javax.servlet.Filter; 6import jakarta.servlet.Filter;
7import javax.servlet.FilterChain; 7import jakarta.servlet.FilterChain;
8import javax.servlet.FilterConfig; 8import jakarta.servlet.FilterConfig;
9import javax.servlet.ServletException; 9import jakarta.servlet.ServletException;
10import javax.servlet.ServletRequest; 10import jakarta.servlet.ServletRequest;
11import javax.servlet.ServletResponse; 11import jakarta.servlet.ServletResponse;
12import javax.servlet.http.HttpServletRequest; 12import jakarta.servlet.http.HttpServletRequest;
13import javax.servlet.http.HttpServletResponse; 13import jakarta.servlet.http.HttpServletResponse;
14 14
15public class CacheControlFilter implements Filter { 15public class CacheControlFilter implements Filter {
16 16
diff --git a/language-web/src/main/java/tools/refinery/language/web/ProblemServlet.java b/language-web/src/main/java/tools/refinery/language/web/ProblemServlet.java
index d249525f..49457002 100644
--- a/language-web/src/main/java/tools/refinery/language/web/ProblemServlet.java
+++ b/language-web/src/main/java/tools/refinery/language/web/ProblemServlet.java
@@ -3,29 +3,27 @@
3 */ 3 */
4package tools.refinery.language.web; 4package tools.refinery.language.web;
5 5
6import javax.servlet.ServletException;
7
8import org.eclipse.xtext.util.DisposableRegistry; 6import org.eclipse.xtext.util.DisposableRegistry;
9import org.eclipse.xtext.web.servlet.XtextServlet; 7
8import jakarta.servlet.ServletException;
9import tools.refinery.language.web.xtext.XtextServlet;
10 10
11/** 11/**
12 * 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.
13 */ 13 */
14public class ProblemServlet extends XtextServlet { 14public class ProblemServlet extends XtextServlet {
15 15
16 private static final long serialVersionUID = 1L; 16 private static final long serialVersionUID = -9204695886561362912L;
17 17
18 // Xtext requires a mutable servlet instance field. 18 private transient DisposableRegistry disposableRegistry;
19 @SuppressWarnings("squid:S2226") 19
20 private DisposableRegistry disposableRegistry;
21
22 @Override 20 @Override
23 public void init() throws ServletException { 21 public void init() throws ServletException {
24 super.init(); 22 super.init();
25 var injector = new ProblemWebSetup().createInjectorAndDoEMFRegistration(); 23 var injector = new ProblemWebSetup().createInjectorAndDoEMFRegistration();
26 this.disposableRegistry = injector.getInstance(DisposableRegistry.class); 24 this.disposableRegistry = injector.getInstance(DisposableRegistry.class);
27 } 25 }
28 26
29 @Override 27 @Override
30 public void destroy() { 28 public void destroy() {
31 if (disposableRegistry != null) { 29 if (disposableRegistry != null) {
@@ -34,5 +32,5 @@ public class ProblemServlet extends XtextServlet {
34 } 32 }
35 super.destroy(); 33 super.destroy();
36 } 34 }
37 35
38} 36}
diff --git a/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java b/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
index c6ee94dc..c253422b 100644
--- a/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
+++ b/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
@@ -11,16 +11,17 @@ import java.net.URISyntaxException;
11import java.util.EnumSet; 11import java.util.EnumSet;
12import java.util.Set; 12import java.util.Set;
13 13
14import javax.servlet.DispatcherType;
15import javax.servlet.SessionTrackingMode;
16
17import org.eclipse.jetty.server.Server; 14import org.eclipse.jetty.server.Server;
18import org.eclipse.jetty.server.session.SessionHandler; 15import org.eclipse.jetty.server.session.SessionHandler;
19import org.eclipse.jetty.servlet.DefaultServlet; 16import org.eclipse.jetty.servlet.DefaultServlet;
20import org.eclipse.jetty.servlet.ServletContextHandler; 17import org.eclipse.jetty.servlet.ServletContextHandler;
21import org.eclipse.jetty.servlet.ServletHolder; 18import org.eclipse.jetty.servlet.ServletHolder;
22import org.eclipse.jetty.util.log.Slf4jLog;
23import org.eclipse.jetty.util.resource.Resource; 19import org.eclipse.jetty.util.resource.Resource;
20import org.slf4j.Logger;
21import org.slf4j.LoggerFactory;
22
23import jakarta.servlet.DispatcherType;
24import jakarta.servlet.SessionTrackingMode;
24 25
25public class ServerLauncher { 26public class ServerLauncher {
26 public static final String DEFAULT_LISTEN_ADDRESS = "localhost"; 27 public static final String DEFAULT_LISTEN_ADDRESS = "localhost";
@@ -30,7 +31,7 @@ public class ServerLauncher {
30 // Use this cookie name for load balancing. 31 // Use this cookie name for load balancing.
31 public static final String SESSION_COOKIE_NAME = "JSESSIONID"; 32 public static final String SESSION_COOKIE_NAME = "JSESSIONID";
32 33
33 private static final Slf4jLog LOG = new Slf4jLog(ServerLauncher.class.getName()); 34 private static final Logger LOG = LoggerFactory.getLogger(ServerLauncher.class);
34 35
35 private final Server server; 36 private final Server server;
36 37
@@ -71,15 +72,8 @@ public class ServerLauncher {
71 72
72 public void start() throws Exception { 73 public void start() throws Exception {
73 server.start(); 74 server.start();
74 LOG.info("Server started " + server.getURI() + "..."); 75 LOG.info("Server started on {}", server.getURI());
75 LOG.info("Press enter to stop the server..."); 76 server.join();
76 int key = System.in.read();
77 if (key != -1) {
78 server.stop();
79 } else {
80 LOG.warn("Console input is not available. "
81 + "In order to stop the server, you need to cancel process manually.");
82 }
83 } 77 }
84 78
85 public static void main(String[] args) { 79 public static void main(String[] args) {
@@ -89,7 +83,7 @@ public class ServerLauncher {
89 var serverLauncher = new ServerLauncher(bindAddress, baseResource); 83 var serverLauncher = new ServerLauncher(bindAddress, baseResource);
90 serverLauncher.start(); 84 serverLauncher.start();
91 } catch (Exception exception) { 85 } catch (Exception exception) {
92 LOG.warn(exception); 86 LOG.error("Fatal server error", exception);
93 System.exit(1); 87 System.exit(1);
94 } 88 }
95 } 89 }
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/HttpServiceContext.java b/language-web/src/main/java/tools/refinery/language/web/xtext/HttpServiceContext.java
new file mode 100644
index 00000000..d0ba6a2d
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/HttpServiceContext.java
@@ -0,0 +1,107 @@
1/**
2 * Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 */
9package tools.refinery.language.web.xtext;
10
11import java.io.IOException;
12import java.net.URLDecoder;
13import java.nio.charset.Charset;
14import java.util.Collections;
15import java.util.Enumeration;
16import java.util.HashMap;
17import java.util.Map;
18import java.util.Set;
19
20import org.eclipse.xtext.web.server.IServiceContext;
21import org.eclipse.xtext.web.server.ISession;
22
23import com.google.common.io.CharStreams;
24
25import jakarta.servlet.http.HttpServletRequest;
26
27/**
28 * Provides the parameters and metadata of an {@link HttpServletRequest}.
29 */
30class HttpServiceContext implements IServiceContext {
31 private final HttpServletRequest request;
32
33 private final Map<String, String> parameters = new HashMap<>();
34
35 private HttpSessionWrapper sessionWrapper;
36
37 public HttpServiceContext(HttpServletRequest request) throws IOException {
38 this.request = request;
39 initializeParameters();
40 }
41
42 private void initializeParameters() throws IOException {
43 initializeUrlEncodedParameters();
44 initializeRequestParameters();
45 if (!parameters.containsKey(IServiceContext.SERVICE_TYPE)) {
46 String substring = null;
47 if (request.getPathInfo() != null) {
48 substring = request.getPathInfo().substring(1);
49 }
50 parameters.put(IServiceContext.SERVICE_TYPE, substring);
51 }
52 }
53
54 private void initializeUrlEncodedParameters() throws IOException {
55 String[] contentType = null;
56 if (request.getContentType() != null) {
57 contentType = request.getContentType().split(";(\\s*)");
58 }
59 if (contentType != null && "application/x-www-form-urlencoded".equals(contentType[0])) {
60 String charset = null;
61 if (contentType.length >= 2 && contentType[1].startsWith("charset=")) {
62 charset = (contentType[1]).substring("charset=".length());
63 } else {
64 charset = Charset.defaultCharset().toString();
65 }
66 String[] encodedParams = CharStreams.toString(request.getReader()).split("&");
67 for (String param : encodedParams) {
68 int nameEnd = param.indexOf("=");
69 if (nameEnd > 0) {
70 String key = param.substring(0, nameEnd);
71 String value = URLDecoder.decode(param.substring(nameEnd + 1), charset);
72 parameters.put(key, value);
73 }
74 }
75 }
76 }
77
78 private void initializeRequestParameters() {
79 Enumeration<String> paramNames = request.getParameterNames();
80 while (paramNames.hasMoreElements()) {
81 String name = paramNames.nextElement();
82 parameters.put(name, request.getParameter(name));
83 }
84 }
85
86 @Override
87 public Set<String> getParameterKeys() {
88 return Collections.unmodifiableSet(parameters.keySet());
89 }
90
91 @Override
92 public String getParameter(String key) {
93 return parameters.get(key);
94 }
95
96 @Override
97 public ISession getSession() {
98 if (sessionWrapper == null) {
99 sessionWrapper = new HttpSessionWrapper(request.getSession(true));
100 }
101 return sessionWrapper;
102 }
103
104 public HttpServletRequest getRequest() {
105 return request;
106 }
107}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/HttpSessionWrapper.java b/language-web/src/main/java/tools/refinery/language/web/xtext/HttpSessionWrapper.java
new file mode 100644
index 00000000..8a5e19ba
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/HttpSessionWrapper.java
@@ -0,0 +1,53 @@
1/**
2 * Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 */
9package tools.refinery.language.web.xtext;
10
11import org.eclipse.xtext.web.server.ISession;
12import org.eclipse.xtext.xbase.lib.Functions.Function0;
13
14import jakarta.servlet.http.HttpSession;
15
16/**
17 * Provides access to the information stored in a {@link HttpSession}.
18 */
19record HttpSessionWrapper(HttpSession session) implements ISession {
20 @SuppressWarnings("unchecked")
21 @Override
22 public <T> T get(Object key) {
23 return (T) session.getAttribute(key.toString());
24 }
25
26 @Override
27 public <T> T get(Object key, Function0<? extends T> factory) {
28 synchronized (session) {
29 T sessionValue = get(key);
30 if (sessionValue != null) {
31 return sessionValue;
32 } else {
33 T factoryValue = factory.apply();
34 put(key, factoryValue);
35 return factoryValue;
36 }
37 }
38 }
39
40 @Override
41 public void put(Object key, Object value) {
42 session.setAttribute(key.toString(), value);
43 }
44
45 @Override
46 public void remove(Object key) {
47 session.removeAttribute(key.toString());
48 }
49
50 public HttpSession getSession() {
51 return session;
52 }
53}
diff --git a/language-web/src/main/java/tools/refinery/language/web/xtext/XtextServlet.java b/language-web/src/main/java/tools/refinery/language/web/xtext/XtextServlet.java
new file mode 100644
index 00000000..f39bec12
--- /dev/null
+++ b/language-web/src/main/java/tools/refinery/language/web/xtext/XtextServlet.java
@@ -0,0 +1,196 @@
1/**
2 * Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-2.0.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 */
9package tools.refinery.language.web.xtext;
10
11import java.io.IOException;
12import java.util.Set;
13
14import org.eclipse.emf.common.util.URI;
15import org.eclipse.xtext.resource.IResourceServiceProvider;
16import org.eclipse.xtext.web.server.IServiceContext;
17import org.eclipse.xtext.web.server.IServiceResult;
18import org.eclipse.xtext.web.server.IUnwrappableServiceResult;
19import org.eclipse.xtext.web.server.InvalidRequestException;
20import org.eclipse.xtext.web.server.XtextServiceDispatcher;
21import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
24import com.google.common.base.Objects;
25import com.google.common.base.Strings;
26import com.google.gson.Gson;
27import com.google.inject.Injector;
28
29import jakarta.servlet.ServletException;
30import jakarta.servlet.http.HttpServlet;
31import jakarta.servlet.http.HttpServletRequest;
32import jakarta.servlet.http.HttpServletResponse;
33
34/**
35 * An HTTP servlet for publishing the Xtext services. Include this into your web
36 * server by creating a subclass that executes the standalone setups of your
37 * languages in its {@link #init()} method:
38 *
39 * <pre>
40 * &#64;WebServlet(name = "Xtext Services", urlPatterns = "/xtext-service/*")
41 * class MyXtextServlet extends XtextServlet {
42 * override init() {
43 * super.init();
44 * MyDslWebSetup.doSetup();
45 * }
46 * }
47 * </pre>
48 *
49 * Use the {@code WebServlet} annotation to register your servlet. The default
50 * URL pattern for Xtext services is {@code "/xtext-service/*"}.
51 */
52public class XtextServlet extends HttpServlet {
53
54 private static final long serialVersionUID = 7784324070547781918L;
55
56 private static final IResourceServiceProvider.Registry SERVICE_PROVIDER_REGISTRY = IResourceServiceProvider.Registry.INSTANCE;
57
58 private static final String ENCODING = "UTF-8";
59
60 private static final String INVALID_REQUEST_MESSAGE = "Invalid request ({}): {}";
61
62 private final transient Logger log = LoggerFactory.getLogger(this.getClass());
63
64 private final transient Gson gson = new Gson();
65
66 @Override
67 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
68 try {
69 super.service(req, resp);
70 } catch (InvalidRequestException.ResourceNotFoundException exception) {
71 log.trace(INVALID_REQUEST_MESSAGE, req.getRequestURI(), exception.getMessage());
72 resp.sendError(HttpServletResponse.SC_NOT_FOUND, exception.getMessage());
73 } catch (InvalidRequestException.InvalidDocumentStateException exception) {
74 log.trace(INVALID_REQUEST_MESSAGE, req.getRequestURI(), exception.getMessage());
75 resp.sendError(HttpServletResponse.SC_CONFLICT, exception.getMessage());
76 } catch (InvalidRequestException.PermissionDeniedException exception) {
77 log.trace(INVALID_REQUEST_MESSAGE, req.getRequestURI(), exception.getMessage());
78 resp.sendError(HttpServletResponse.SC_FORBIDDEN, exception.getMessage());
79 } catch (InvalidRequestException exception) {
80 log.trace(INVALID_REQUEST_MESSAGE, req.getRequestURI(), exception.getMessage());
81 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, exception.getMessage());
82 }
83 }
84
85 @Override
86 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
87 XtextServiceDispatcher.ServiceDescriptor service = getService(req);
88 if (!service.isHasConflict() && (service.isHasSideEffects() || hasTextInput(service))) {
89 super.doGet(req, resp);
90 } else {
91 doService(service, resp);
92 }
93 }
94
95 @Override
96 protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
97 XtextServiceDispatcher.ServiceDescriptor service = getService(req);
98 String type = service.getContext().getParameter(IServiceContext.SERVICE_TYPE);
99 if (!service.isHasConflict() && !Objects.equal(type, "update")) {
100 super.doPut(req, resp);
101 } else {
102 doService(service, resp);
103 }
104 }
105
106 @Override
107 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
108 XtextServiceDispatcher.ServiceDescriptor service = getService(req);
109 String type = service.getContext().getParameter(IServiceContext.SERVICE_TYPE);
110 if (!service.isHasConflict()
111 && (!service.isHasSideEffects() && !hasTextInput(service) || Objects.equal(type, "update"))) {
112 super.doPost(req, resp);
113 } else {
114 doService(service, resp);
115 }
116 }
117
118 protected boolean hasTextInput(XtextServiceDispatcher.ServiceDescriptor service) {
119 Set<String> parameterKeys = service.getContext().getParameterKeys();
120 return parameterKeys.contains("fullText") || parameterKeys.contains("deltaText");
121 }
122
123 /**
124 * Retrieve the service metadata for the given request. This involves resolving
125 * the Guice injector for the respective language, querying the
126 * {@link XtextServiceDispatcher}, and checking the permission to invoke the
127 * service.
128 */
129 protected XtextServiceDispatcher.ServiceDescriptor getService(HttpServletRequest request) throws IOException {
130 HttpServiceContext serviceContext = new HttpServiceContext(request);
131 Injector injector = getInjector(serviceContext);
132 XtextServiceDispatcher serviceDispatcher = injector.getInstance(XtextServiceDispatcher.class);
133 return serviceDispatcher.getService(serviceContext);
134 }
135
136 /**
137 * Invoke the service function of the given service descriptor and write its
138 * result to the servlet response in Json format. An exception is made for
139 * {@link IUnwrappableServiceResult}: here the document itself is written into
140 * the response instead of wrapping it into a Json object.
141 */
142 protected void doService(XtextServiceDispatcher.ServiceDescriptor service, HttpServletResponse response)
143 throws IOException {
144 IServiceResult result = service.getService().apply();
145 response.setStatus(HttpServletResponse.SC_OK);
146 response.setCharacterEncoding(ENCODING);
147 response.setHeader("Cache-Control", "no-cache");
148 if (result instanceof IUnwrappableServiceResult unwrapResult && unwrapResult.getContent() != null) {
149 String contentType = null;
150 if (unwrapResult.getContentType() != null) {
151 contentType = unwrapResult.getContentType();
152 } else {
153 contentType = "text/plain";
154 }
155 response.setContentType(contentType);
156 response.getWriter().write(unwrapResult.getContent());
157 } else {
158 response.setContentType("text/x-json");
159 gson.toJson(result, response.getWriter());
160 }
161 }
162
163 /**
164 * Resolve the Guice injector for the language associated with the given
165 * context.
166 */
167 protected Injector getInjector(HttpServiceContext serviceContext)
168 throws InvalidRequestException.UnknownLanguageException {
169 IResourceServiceProvider resourceServiceProvider = null;
170 String parameter = serviceContext.getParameter("resource");
171 if (parameter == null) {
172 parameter = "";
173 }
174 URI emfURI = URI.createURI(parameter);
175 String contentType = serviceContext.getParameter("contentType");
176 if (Strings.isNullOrEmpty(contentType)) {
177 resourceServiceProvider = SERVICE_PROVIDER_REGISTRY.getResourceServiceProvider(emfURI);
178 if (resourceServiceProvider == null) {
179 if (emfURI.toString().isEmpty()) {
180 throw new InvalidRequestException.UnknownLanguageException(
181 "Unable to identify the Xtext language: missing parameter 'resource' or 'contentType'.");
182 } else {
183 throw new InvalidRequestException.UnknownLanguageException(
184 "Unable to identify the Xtext language for resource " + emfURI + ".");
185 }
186 }
187 } else {
188 resourceServiceProvider = SERVICE_PROVIDER_REGISTRY.getResourceServiceProvider(emfURI, contentType);
189 if (resourceServiceProvider == null) {
190 throw new InvalidRequestException.UnknownLanguageException(
191 "Unable to identify the Xtext language for contentType " + contentType + ".");
192 }
193 }
194 return resourceServiceProvider.get(Injector.class);
195 }
196} \ No newline at end of file