summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/terminal/gwt/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/vaadin/terminal/gwt/server')
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java16
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java12
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java3
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java22
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapDom.java9
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapHandler.java257
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapListener.java11
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapResponse.java72
-rw-r--r--src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java9
-rw-r--r--src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java5
-rw-r--r--src/com/vaadin/terminal/gwt/server/VaadinContext.java61
-rw-r--r--src/com/vaadin/terminal/gwt/server/VaadinContextEvent.java19
-rw-r--r--src/com/vaadin/terminal/gwt/server/VaadinContextListener.java13
13 files changed, 389 insertions, 120 deletions
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
index 363f7e4869..bb4e8ba0a7 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
@@ -290,6 +290,9 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
}
};
+ private final VaadinContext vaadinContext = new VaadinContext(
+ getDeploymentConfiguration());
+
@Override
public void init(PortletConfig config) throws PortletException {
super.init(config);
@@ -315,6 +318,15 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
checkProductionMode();
checkCrossSiteProtection();
+
+ vaadinContext.init();
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+
+ vaadinContext.destroy();
}
private void checkCrossSiteProtection() {
@@ -787,8 +799,8 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet
application.setLocale(locale);
// No application URL when running inside a portlet
application.start(new ApplicationStartEvent(null,
- getDeploymentConfiguration().getInitParameters(),
- context, isProductionMode()));
+ getDeploymentConfiguration().getInitParameters(), context,
+ isProductionMode()));
}
}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
index a0e807801e..c2e1d2d3e7 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
@@ -128,6 +128,9 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements
}
};
+ private final VaadinContext vaadinContext = new VaadinContext(
+ getDeploymentConfiguration());
+
/**
* Called by the servlet container to indicate to a servlet that the servlet
* is being placed into service.
@@ -166,6 +169,15 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements
checkProductionMode();
checkCrossSiteProtection();
checkResourceCacheTime();
+
+ vaadinContext.init();
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+
+ vaadinContext.destroy();
}
private void checkCrossSiteProtection() {
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
index ba1b3cadb6..b87aaa278b 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
@@ -2394,7 +2394,8 @@ public abstract class AbstractCommunicationManager implements Serializable {
// Use the same logic as for determined roots
BootstrapHandler bootstrapHandler = getBootstrapHandler();
BootstrapContext context = bootstrapHandler.createContext(
- combinedRequest, response, application, root.getRootId());
+ combinedRequest, response, application, root.getRootId(),
+ null);
String widgetset = context.getWidgetsetName();
String theme = context.getThemeName();
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java b/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java
index 1ac090ad76..47bf5ecc60 100644
--- a/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java
+++ b/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java
@@ -5,7 +5,9 @@
package com.vaadin.terminal.gwt.server;
import java.lang.reflect.Constructor;
+import java.util.Iterator;
import java.util.Properties;
+import java.util.ServiceLoader;
import com.vaadin.terminal.DeploymentConfiguration;
@@ -14,6 +16,7 @@ public abstract class AbstractDeploymentConfiguration implements
private final Class<?> systemPropertyBaseClass;
private final Properties applicationProperties = new Properties();
+ private VaadinContext vaadinContext;
public AbstractDeploymentConfiguration(Class<?> systemPropertyBaseClass) {
this.systemPropertyBaseClass = systemPropertyBaseClass;
@@ -118,4 +121,23 @@ public abstract class AbstractDeploymentConfiguration implements
public Properties getInitParameters() {
return applicationProperties;
}
+
+ @Override
+ public Iterator<VaadinContextListener> getContextListeners() {
+ // Called once for init and once for destroy, so it's probably not worth
+ // the effort caching the ServiceLoader instance
+ ServiceLoader<VaadinContextListener> contextListenerLoader = ServiceLoader
+ .load(VaadinContextListener.class, getClassLoader());
+ return contextListenerLoader.iterator();
+ }
+
+ @Override
+ public void setVaadinContext(VaadinContext vaadinContext) {
+ this.vaadinContext = vaadinContext;
+ }
+
+ @Override
+ public VaadinContext getVaadinContext() {
+ return vaadinContext;
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapDom.java b/src/com/vaadin/terminal/gwt/server/BootstrapDom.java
new file mode 100644
index 0000000000..4731a5b79f
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/server/BootstrapDom.java
@@ -0,0 +1,9 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.server;
+
+public class BootstrapDom {
+
+}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java b/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java
index 4038b8f1bc..d025e93072 100644
--- a/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java
+++ b/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java
@@ -8,11 +8,19 @@ import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Serializable;
-import java.io.Writer;
+import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
import javax.servlet.http.HttpServletResponse;
+import org.jsoup.nodes.DataNode;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.DocumentType;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+
import com.vaadin.Application;
import com.vaadin.RootRequiresMoreInformationException;
import com.vaadin.Version;
@@ -31,24 +39,16 @@ public abstract class BootstrapHandler implements RequestHandler {
protected class BootstrapContext implements Serializable {
private final WrappedResponse response;
- private final WrappedRequest request;
- private final Application application;
- private final Integer rootId;
+ private final BootstrapResponse bootstrapResponse;
- private Writer writer;
- private Root root;
private String widgetsetName;
private String themeName;
private String appId;
- private boolean rootFetched = false;
-
public BootstrapContext(WrappedResponse response,
- WrappedRequest request, Application application, Integer rootId) {
+ BootstrapResponse bootstrapResponse) {
this.response = response;
- this.request = request;
- this.application = application;
- this.rootId = rootId;
+ this.bootstrapResponse = bootstrapResponse;
}
public WrappedResponse getResponse() {
@@ -56,32 +56,19 @@ public abstract class BootstrapHandler implements RequestHandler {
}
public WrappedRequest getRequest() {
- return request;
+ return bootstrapResponse.getRequest();
}
public Application getApplication() {
- return application;
- }
-
- public Writer getWriter() throws IOException {
- if (writer == null) {
- response.setContentType("text/html");
- writer = new BufferedWriter(new OutputStreamWriter(
- response.getOutputStream(), "UTF-8"));
- }
- return writer;
+ return bootstrapResponse.getApplication();
}
public Integer getRootId() {
- return rootId;
+ return bootstrapResponse.getRootId();
}
public Root getRoot() {
- if (!rootFetched) {
- root = Root.getCurrent();
- rootFetched = true;
- }
- return root;
+ return bootstrapResponse.getRoot();
}
public String getWidgetsetName() {
@@ -111,6 +98,10 @@ public abstract class BootstrapHandler implements RequestHandler {
return appId;
}
+ public BootstrapResponse getBootstrapResponse() {
+ return bootstrapResponse;
+ }
+
}
@Override
@@ -145,8 +136,9 @@ public abstract class BootstrapHandler implements RequestHandler {
WrappedResponse response, Application application, Integer rootId)
throws IOException, JSONException {
+ Map<String, Object> headers = new LinkedHashMap<String, Object>();
BootstrapContext context = createContext(request, response,
- application, rootId);
+ application, rootId, headers);
DeploymentConfiguration deploymentConfiguration = request
.getDeploymentConfiguration();
@@ -154,28 +146,61 @@ public abstract class BootstrapHandler implements RequestHandler {
boolean standalone = deploymentConfiguration.isStandalone(request);
if (standalone) {
setBootstrapPageHeaders(context);
- writeBootstrapPageHtmlHeadStart(context);
- writeBootstrapPageHtmlHeader(context);
- writeBootstrapPageHtmlBodyStart(context);
+ setBasicHtml(context);
+ setBootstrapPageHtmlHeader(context);
+ setBodyTag(context);
}
- // TODO include initial UIDL in the scripts?
- writeBootstrapPageHtmlVaadinScripts(context);
+ setBootstrapPageHtmlVaadinScripts(context);
+
+ setMainDiv(context);
- writeBootstrapPageHtmlMainDiv(context);
+ request.getDeploymentConfiguration().getVaadinContext()
+ .fireModifyBootstrapEvent(context.getBootstrapResponse());
- Writer page = context.getWriter();
+ response.setContentType("text/html");
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
+ response.getOutputStream(), "UTF-8"));
if (standalone) {
- page.write("</body>\n</html>\n");
+ Set<Entry<String, Object>> entrySet = headers.entrySet();
+ for (Entry<String, Object> header : entrySet) {
+ Object value = header.getValue();
+ if (value instanceof String) {
+ response.setHeader(header.getKey(), (String) value);
+ } else if (value instanceof Long) {
+ response.setDateHeader(header.getKey(),
+ ((Long) value).longValue());
+ } else {
+ throw new RuntimeException("Unsupported header value: "
+ + value);
+ }
+ }
+ writer.append(context.getBootstrapResponse().getDocument()
+ .outerHtml());
+ } else {
+ writer.append(context.getBootstrapResponse().getApplicationTag()
+ .outerHtml());
}
-
- page.close();
+ writer.close();
}
public BootstrapContext createContext(WrappedRequest request,
- WrappedResponse response, Application application, Integer rootId) {
- BootstrapContext context = new BootstrapContext(response, request,
- application, rootId);
+ WrappedResponse response, Application application, Integer rootId,
+ Map<String, Object> headers) {
+ boolean standalone = request.getDeploymentConfiguration().isStandalone(
+ request);
+ Document document;
+ Element applicationTag;
+ if (standalone) {
+ document = Document.createShell("");
+ applicationTag = document.body();
+ } else {
+ document = null;
+ applicationTag = new Element(Tag.valueOf("div"), "");
+ }
+ BootstrapContext context = new BootstrapContext(response,
+ new BootstrapResponse(this, request, document, applicationTag,
+ headers, application, rootId));
return context;
}
@@ -219,9 +244,7 @@ public abstract class BootstrapHandler implements RequestHandler {
*
* @throws IOException
*/
- protected void writeBootstrapPageHtmlMainDiv(BootstrapContext context)
- throws IOException {
- Writer page = context.getWriter();
+ protected void setMainDiv(BootstrapContext context) throws IOException {
String style = getMainDivStyle(context);
/*- Add classnames;
@@ -237,14 +260,16 @@ public abstract class BootstrapHandler implements RequestHandler {
String classNames = "v-app " + appClass;
+ Element applicationTag = context.getBootstrapResponse()
+ .getApplicationTag();
+ Element mainDiv = applicationTag.appendElement("div");
+ mainDiv.attr("id", context.getAppId());
+ mainDiv.addClass(classNames);
if (style != null && style.length() != 0) {
- style = " style=\"" + style + "\"";
+ mainDiv.attr("style", style);
}
- page.write("<div id=\"" + context.getAppId() + "\" class=\""
- + classNames + "\"" + style + ">");
- page.write("<div class=\"v-app-loading\"></div>");
- page.write("</div>\n");
- page.write("<noscript>" + getNoScriptMessage() + "</noscript>");
+ mainDiv.appendElement("div").addClass("v-app-loading");
+ mainDiv.appendElement("noscript").append(getNoScriptMessage());
}
/**
@@ -279,11 +304,10 @@ public abstract class BootstrapHandler implements RequestHandler {
*
* @throws IOException
*/
- protected void writeBootstrapPageHtmlBodyStart(BootstrapContext context)
- throws IOException {
- Writer page = context.getWriter();
- page.write("\n</head>\n<body scroll=\"auto\" class=\""
- + ApplicationConnection.GENERATED_BODY_CLASSNAME + "\">\n");
+ protected void setBodyTag(BootstrapContext context) throws IOException {
+ Element body = context.getBootstrapResponse().getDocument().body();
+ body.attr("scroll", "auto");
+ body.addClass(ApplicationConnection.GENERATED_BODY_CLASSNAME);
}
/**
@@ -297,61 +321,70 @@ public abstract class BootstrapHandler implements RequestHandler {
* @throws IOException
* @throws JSONException
*/
- protected void writeBootstrapPageHtmlVaadinScripts(BootstrapContext context)
+ protected void setBootstrapPageHtmlVaadinScripts(BootstrapContext context)
throws IOException, JSONException {
WrappedRequest request = context.getRequest();
- Writer page = context.getWriter();
DeploymentConfiguration deploymentConfiguration = request
.getDeploymentConfiguration();
String staticFileLocation = deploymentConfiguration
.getStaticFileLocation(request);
- page.write("<iframe tabIndex=\"-1\" id=\"__gwt_historyFrame\" "
- + "style=\"position:absolute;width:0;height:0;border:0;overflow:"
- + "hidden;\" src=\"javascript:false\"></iframe>");
+ Element applicationTag = context.getBootstrapResponse()
+ .getApplicationTag();
+
+ applicationTag
+ .appendElement("iframe")
+ .attr("tabIndex", "-1")
+ .attr("id", "__gwt_historyFrame")
+ .attr("style",
+ "position:absolute;width:0;height:0;border:0;overflow:hidden")
+ .attr("src", "javascript:false");
String bootstrapLocation = staticFileLocation
+ "/VAADIN/vaadinBootstrap.js";
- page.write("<script type=\"text/javascript\" src=\"");
- page.write(bootstrapLocation);
- page.write("\"></script>\n");
-
- page.write("<script type=\"text/javascript\">\n");
- page.write("//<![CDATA[\n");
- page.write("if (!window.vaadin) alert("
+ applicationTag.appendElement("script").attr("type", "text/javascript")
+ .attr("src", bootstrapLocation);
+ Element mainScriptTag = applicationTag.appendElement("script").attr(
+ "type", "text/javascript");
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("//<![CDATA[\n");
+ builder.append("if (!window.vaadin) alert("
+ JSONObject.quote("Failed to load the bootstrap javascript: "
+ bootstrapLocation) + ");\n");
- writeMainScriptTagContents(context);
- page.write("//]]>\n</script>\n");
+ appendMainScriptTagContents(context, builder);
+
+ builder.append("//]]>");
+ mainScriptTag.appendChild(new DataNode(builder.toString(),
+ mainScriptTag.baseUri()));
}
- protected void writeMainScriptTagContents(BootstrapContext context)
- throws JSONException, IOException {
+ protected void appendMainScriptTagContents(BootstrapContext context,
+ StringBuilder builder) throws JSONException, IOException {
JSONObject defaults = getDefaultParameters(context);
JSONObject appConfig = getApplicationParameters(context);
boolean isDebug = !context.getApplication().isProductionMode();
- Writer page = context.getWriter();
- page.write("vaadin.setDefaults(");
- printJsonObject(page, defaults, isDebug);
- page.write(");\n");
+ builder.append("vaadin.setDefaults(");
+ appendJsonObject(builder, defaults, isDebug);
+ builder.append(");\n");
- page.write("vaadin.initApplication(\"");
- page.write(context.getAppId());
- page.write("\",");
- printJsonObject(page, appConfig, isDebug);
- page.write(");\n");
+ builder.append("vaadin.initApplication(\"");
+ builder.append(context.getAppId());
+ builder.append("\",");
+ appendJsonObject(builder, appConfig, isDebug);
+ builder.append(");\n");
}
- private static void printJsonObject(Writer page, JSONObject jsonObject,
- boolean isDebug) throws IOException, JSONException {
+ private static void appendJsonObject(StringBuilder builder,
+ JSONObject jsonObject, boolean isDebug) throws JSONException {
if (isDebug) {
- page.write(jsonObject.toString(4));
+ builder.append(jsonObject.toString(4));
} else {
- page.write(jsonObject.toString());
+ builder.append(jsonObject.toString());
}
}
@@ -456,36 +489,37 @@ public abstract class BootstrapHandler implements RequestHandler {
*
* @throws IOException
*/
- protected void writeBootstrapPageHtmlHeader(BootstrapContext context)
+ protected void setBootstrapPageHtmlHeader(BootstrapContext context)
throws IOException {
- Writer page = context.getWriter();
String themeName = context.getThemeName();
-
- page.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n");
+ Element head = context.getBootstrapResponse().getDocument().head();
+ head.appendElement("meta").attr("http-equiv", "Content-Type")
+ .attr("content", "text/html; charset=utf-8");
// Chrome frame in all versions of IE (only if Chrome frame is
// installed)
- page.write("<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\"/>\n");
+ head.appendElement("meta").attr("http-equiv", "X-UA-Compatible")
+ .attr("content", "chrome=1");
- page.write("<style type=\"text/css\">"
- + "html, body {height:100%;margin:0;}</style>\n");
+ head.appendElement("style").attr("type", "text/css")
+ .appendText("html, body {height:100%;margin:0;}");
// Add favicon links
if (themeName != null) {
String themeUri = getThemeUri(context, themeName);
- page.write("<link rel=\"shortcut icon\" type=\"image/vnd.microsoft.icon\" href=\""
- + themeUri + "/favicon.ico\" />\n");
- page.write("<link rel=\"icon\" type=\"image/vnd.microsoft.icon\" href=\""
- + themeUri + "/favicon.ico\" />\n");
+ head.appendElement("link").attr("rel", "shortcut icon")
+ .attr("type", "image/vnd.microsoft.icon")
+ .attr("href", themeUri + "/favicon.ico");
+ head.appendElement("link").attr("rel", "icon")
+ .attr("type", "image/vnd.microsoft.icon")
+ .attr("href", themeUri + "/favicon.ico");
}
Root root = context.getRoot();
String title = ((root == null || root.getCaption() == null) ? "" : root
.getCaption());
- page.write("<title>"
- + AbstractApplicationServlet.safeEscapeForHtml(title)
- + "</title>\n");
+ head.appendElement("title").appendText(title);
}
/**
@@ -517,18 +551,21 @@ public abstract class BootstrapHandler implements RequestHandler {
* @param context
* @throws IOException
*/
- protected void writeBootstrapPageHtmlHeadStart(BootstrapContext context)
- throws IOException {
- Writer page = context.getWriter();
+ protected void setBasicHtml(BootstrapContext context) throws IOException {
// write html header
- page.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD "
- + "XHTML 1.0 Transitional//EN\" "
- + "\"http://www.w3.org/TR/xhtml1/"
- + "DTD/xhtml1-transitional.dtd\">\n");
-
- page.write("<html xmlns=\"http://www.w3.org/1999/xhtml\""
- + ">\n<head>\n");
+ // page.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD "
+ // + "XHTML 1.0 Transitional//EN\" "
+ // + "\"http://www.w3.org/TR/xhtml1/"
+ // + "DTD/xhtml1-transitional.dtd\">\n");
+ Document document = context.getBootstrapResponse().getDocument();
+ DocumentType doctype = new DocumentType("html",
+ "//W3C//DTD XHTML 1.0 Transitional//EN",
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
+ document.baseUri());
+ document.child(0).before(doctype);
+
+ document.body().parent().attr("xmlns", "http://www.w3.org/1999/xhtml");
}
/**
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapListener.java b/src/com/vaadin/terminal/gwt/server/BootstrapListener.java
new file mode 100644
index 0000000000..54bd13c25a
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/server/BootstrapListener.java
@@ -0,0 +1,11 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.server;
+
+import java.util.EventListener;
+
+public interface BootstrapListener extends EventListener {
+ public void modifyBootstrap(BootstrapResponse response);
+}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapResponse.java b/src/com/vaadin/terminal/gwt/server/BootstrapResponse.java
new file mode 100644
index 0000000000..37b59989f6
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/server/BootstrapResponse.java
@@ -0,0 +1,72 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.server;
+
+import java.util.EventObject;
+import java.util.Map;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import com.vaadin.Application;
+import com.vaadin.terminal.WrappedRequest;
+import com.vaadin.ui.Root;
+
+public class BootstrapResponse extends EventObject {
+ private final Document document;
+ private final WrappedRequest request;
+ private final Map<String, Object> headers;
+ private final Element applicationTag;
+ private final Application application;
+ private final Integer rootId;
+
+ public BootstrapResponse(BootstrapHandler handler, WrappedRequest request,
+ Document document, Element applicationTag,
+ Map<String, Object> headers, Application application, Integer rootId) {
+ super(handler);
+ this.request = request;
+ this.document = document;
+ this.applicationTag = applicationTag;
+ this.headers = headers;
+ this.application = application;
+ this.rootId = rootId;
+ }
+
+ public void setHeader(String name, String value) {
+ headers.put(name, value);
+ }
+
+ public void setDateHeader(String name, long timestamp) {
+ headers.put(name, Long.valueOf(timestamp));
+ }
+
+ public BootstrapHandler getBootstrapHandler() {
+ return (BootstrapHandler) getSource();
+ }
+
+ public WrappedRequest getRequest() {
+ return request;
+ }
+
+ public Document getDocument() {
+ return document;
+ }
+
+ public Element getApplicationTag() {
+ return applicationTag;
+ }
+
+ public Application getApplication() {
+ return application;
+ }
+
+ public Integer getRootId() {
+ return rootId;
+ }
+
+ public Root getRoot() {
+ return Root.getCurrent();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java
index edd970a31f..39c27d05fe 100644
--- a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java
+++ b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java
@@ -100,7 +100,8 @@ public class PortletCommunicationManager extends AbstractCommunicationManager {
}
@Override
- protected void writeMainScriptTagContents(BootstrapContext context)
+ protected void appendMainScriptTagContents(
+ BootstrapContext context, StringBuilder builder)
throws JSONException, IOException {
// fixed base theme to use - all portal pages with Vaadin
// applications will load this exactly once
@@ -112,11 +113,11 @@ public class PortletCommunicationManager extends AbstractCommunicationManager {
&& !portalTheme.equals(context.getThemeName())) {
String portalThemeUri = getThemeUri(context, portalTheme);
// XSS safe - originates from portal properties
- context.getWriter().write(
- "vaadin.loadTheme('" + portalThemeUri + "');");
+ builder.append("vaadin.loadTheme('" + portalThemeUri
+ + "');");
}
- super.writeMainScriptTagContents(context);
+ super.appendMainScriptTagContents(context, builder);
}
@Override
diff --git a/src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java b/src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java
index b2b962b0fd..2a1dc31897 100644
--- a/src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java
+++ b/src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java
@@ -31,9 +31,8 @@ class ServletPortletHelper implements Serializable {
throws ApplicationClassException {
String applicationParameter = deploymentConfiguration
.getInitParameters().getProperty("application");
- String rootParameter = deploymentConfiguration
- .getInitParameters().getProperty(
- Application.ROOT_PARAMETER);
+ String rootParameter = deploymentConfiguration.getInitParameters()
+ .getProperty(Application.ROOT_PARAMETER);
ClassLoader classLoader = deploymentConfiguration.getClassLoader();
if (applicationParameter == null) {
diff --git a/src/com/vaadin/terminal/gwt/server/VaadinContext.java b/src/com/vaadin/terminal/gwt/server/VaadinContext.java
new file mode 100644
index 0000000000..f03044a872
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/server/VaadinContext.java
@@ -0,0 +1,61 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.server;
+
+import java.lang.reflect.Method;
+import java.util.Iterator;
+
+import com.vaadin.event.EventRouter;
+import com.vaadin.terminal.DeploymentConfiguration;
+import com.vaadin.tools.ReflectTools;
+
+public class VaadinContext {
+ private static final Method BOOTSTRAP_GENERATE_METHOD = ReflectTools
+ .findMethod(BootstrapListener.class, "modifyBootstrap",
+ BootstrapResponse.class);
+
+ private final DeploymentConfiguration deploymentConfiguration;
+
+ private final EventRouter eventRouter = new EventRouter();
+
+ public VaadinContext(DeploymentConfiguration deploymentConfiguration) {
+ this.deploymentConfiguration = deploymentConfiguration;
+ deploymentConfiguration.setVaadinContext(this);
+ }
+
+ public DeploymentConfiguration getDeploymentConfiguration() {
+ return deploymentConfiguration;
+ }
+
+ public void init() {
+ VaadinContextEvent event = new VaadinContextEvent(this);
+ Iterator<VaadinContextListener> listeners = deploymentConfiguration
+ .getContextListeners();
+ while (listeners.hasNext()) {
+ VaadinContextListener listener = listeners.next();
+ listener.contextCreated(event);
+ }
+ }
+
+ public void destroy() {
+ VaadinContextEvent event = new VaadinContextEvent(this);
+ Iterator<VaadinContextListener> listeners = deploymentConfiguration
+ .getContextListeners();
+ while (listeners.hasNext()) {
+ VaadinContextListener listener = listeners.next();
+ listener.contextDestoryed(event);
+ }
+ }
+
+ public void addBootstrapListener(BootstrapListener listener) {
+ eventRouter.addListener(BootstrapResponse.class, listener,
+ BOOTSTRAP_GENERATE_METHOD);
+ }
+
+ public void fireModifyBootstrapEvent(BootstrapResponse bootstrapResponse) {
+ eventRouter.fireEvent(bootstrapResponse);
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/server/VaadinContextEvent.java b/src/com/vaadin/terminal/gwt/server/VaadinContextEvent.java
new file mode 100644
index 0000000000..239490433c
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/server/VaadinContextEvent.java
@@ -0,0 +1,19 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.server;
+
+import java.util.EventObject;
+
+public class VaadinContextEvent extends EventObject {
+
+ public VaadinContextEvent(VaadinContext source) {
+ super(source);
+ }
+
+ public VaadinContext getVaadinContext() {
+ return (VaadinContext) getSource();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/server/VaadinContextListener.java b/src/com/vaadin/terminal/gwt/server/VaadinContextListener.java
new file mode 100644
index 0000000000..5e379d9b91
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/server/VaadinContextListener.java
@@ -0,0 +1,13 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.server;
+
+import java.util.EventListener;
+
+public interface VaadinContextListener extends EventListener {
+ public void contextCreated(VaadinContextEvent event);
+
+ public void contextDestoryed(VaadinContextEvent event);
+}