aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorelmot <elmot@vaadin.com>2016-02-29 10:00:00 +0200
committerelmot <elmot@vaadin.com>2016-03-02 14:57:30 +0200
commit46a4710095c00978f03007ac56bbdc513997a86e (patch)
tree126fa9a4149bc135c404aebb5b9449c0aae81f2d
parent83bffb42f708226f10ed92521cb6dcc124047a6c (diff)
downloadvaadin-framework-46a4710095c00978f03007ac56bbdc513997a86e.tar.gz
vaadin-framework-46a4710095c00978f03007ac56bbdc513997a86e.zip
BootstrapListeners as an annotation
Change-Id: I695aad4150dca1f71424f41b5669e404efc71354
-rw-r--r--server/src/com/vaadin/annotations/BootstrapMod.java40
-rw-r--r--server/src/com/vaadin/server/BootstrapHandler.java79
-rw-r--r--uitest/src/com/vaadin/tests/vaadincontext/BootstrapModifyUI.java30
3 files changed, 125 insertions, 24 deletions
diff --git a/server/src/com/vaadin/annotations/BootstrapMod.java b/server/src/com/vaadin/annotations/BootstrapMod.java
new file mode 100644
index 0000000000..3b94929409
--- /dev/null
+++ b/server/src/com/vaadin/annotations/BootstrapMod.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * 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
+ *
+ * http://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.
+ */
+package com.vaadin.annotations;
+
+import com.vaadin.server.BootstrapHandler;
+import com.vaadin.server.BootstrapListener;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Provides various helper methods for connectors. Meant for internal use.
+ *
+ * @author Vaadin Ltd
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface BootstrapMod {
+
+ public Class<? extends BootstrapListener>[] value();
+}
diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java
index a9343a7e03..1e003e41f7 100644
--- a/server/src/com/vaadin/server/BootstrapHandler.java
+++ b/server/src/com/vaadin/server/BootstrapHandler.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
@@ -30,6 +31,7 @@ import java.util.Set;
import javax.servlet.http.HttpServletResponse;
+import com.vaadin.annotations.BootstrapMod;
import org.jsoup.nodes.DataNode;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.DocumentType;
@@ -55,19 +57,16 @@ import elemental.json.JsonObject;
import elemental.json.impl.JsonUtil;
/**
- *
* @author Vaadin Ltd
* @since 7.0.0
- *
* @deprecated As of 7.0. Will likely change or be removed in a future version
*/
@Deprecated
public abstract class BootstrapHandler extends SynchronizedRequestHandler {
/**
- * Parameter that is added to the UI init request if the session has already
- * been restarted when generating the bootstrap HTML and ?restartApplication
- * should thus be ignored when handling the UI init request.
+ * Parameter that is added to the UI init request if the session has already been restarted when generating the
+ * bootstrap HTML and ?restartApplication should thus be ignored when handling the UI init request.
*/
public static final String IGNORE_RESTART_PARAM = "ignoreRestart";
@@ -264,8 +263,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
BootstrapFragmentResponse fragmentResponse = context
.getBootstrapResponse();
session.modifyBootstrapResponse(fragmentResponse);
-
- String html = getBootstrapHtml(context);
+ String html = getBootstrapHtml(context, uiClass);
writeBootstrapPage(response, html);
} catch (JsonException e) {
@@ -275,7 +273,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
return true;
}
- private String getBootstrapHtml(BootstrapContext context) {
+ private String getBootstrapHtml(BootstrapContext context, Class<? extends UI> uiClass) {
VaadinRequest request = context.getRequest();
VaadinResponse response = context.getResponse();
VaadinService vaadinService = request.getService();
@@ -297,6 +295,16 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
setupStandaloneDocument(context, pageResponse);
context.getSession().modifyBootstrapResponse(pageResponse);
+ Class<BootstrapListener>[] uiBootstrapListeners = findBootstrapListeners(uiClass);
+ try {
+ for (Class<BootstrapListener> uiBootstrapListener : uiBootstrapListeners) {
+ uiBootstrapListener.newInstance().modifyBootstrapPage(pageResponse);
+ }
+ } catch (InstantiationException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
sendBootstrapHeaders(response, headers);
@@ -471,15 +479,12 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
}
/**
- * Method to write the div element into which that actual Vaadin application
- * is rendered.
- * <p>
- * Override this method if you want to add some custom html around around
- * the div element into which the actual Vaadin application will be
- * rendered.
- *
+ * Method to write the div element into which that actual Vaadin application is rendered.
+ * <p/>
+ * Override this method if you want to add some custom html around around the div element into which the actual
+ * Vaadin application will be rendered.
+ *
* @param context
- *
* @throws IOException
*/
private void setupMainDiv(BootstrapContext context) throws IOException {
@@ -545,7 +550,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
builder.append("//<![CDATA[\n");
builder.append("if (!window.vaadin) alert("
+ JsonUtil.quote("Failed to load the bootstrap javascript: "
- + bootstrapLocation) + ");\n");
+ + bootstrapLocation) + ");\n");
appendMainScriptTagContents(context, builder);
@@ -694,13 +699,12 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
/**
* Get the URI for the application theme.
- *
- * A portal-wide default theme is fetched from the portal shared resource
- * directory (if any), other themes from the portlet.
- *
+ * <p/>
+ * A portal-wide default theme is fetched from the portal shared resource directory (if any), other themes from the
+ * portlet.
+ *
* @param context
* @param themeName
- *
* @return
*/
public String getThemeUri(BootstrapContext context, String themeName) {
@@ -713,7 +717,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
/**
* Override if required
- *
+ *
* @param context
* @return
*/
@@ -725,7 +729,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
/**
* Do not override.
- *
+ *
* @param context
* @return
*/
@@ -758,4 +762,31 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler {
object.put(key, value);
}
}
+
+ /**
+ * Finds the {@link BootstrapListener}s classes to use for a specific UI. If no listeners are defined, empty array
+ * is returned.
+ * <p/>
+ *
+ * @param uiClass
+ * @return the transport type to use, or empty array
+ */
+ public static Class<BootstrapListener>[] findBootstrapListeners(Class<? extends UI> uiClass) {
+ List<Class<?>> result = new ArrayList<Class<?>>();
+ for (Class<?> tClass = uiClass; tClass != Object.class; tClass = tClass.getSuperclass()) {
+ BootstrapMod annotation = tClass.getAnnotation(BootstrapMod.class);
+ if (annotation != null) {
+ Collections.addAll(result, annotation.value());
+ }
+ }
+
+ for (Class<?> aClass : uiClass.getInterfaces()) {
+ BootstrapMod annotation = aClass.getAnnotation(BootstrapMod.class);
+ if (annotation != null) {
+ Collections.addAll(result, annotation.value());
+ }
+ }
+ //noinspection unchecked
+ return result.toArray(new Class[result.size()]);
+ }
}
diff --git a/uitest/src/com/vaadin/tests/vaadincontext/BootstrapModifyUI.java b/uitest/src/com/vaadin/tests/vaadincontext/BootstrapModifyUI.java
index 3849268bf7..d3aba6075c 100644
--- a/uitest/src/com/vaadin/tests/vaadincontext/BootstrapModifyUI.java
+++ b/uitest/src/com/vaadin/tests/vaadincontext/BootstrapModifyUI.java
@@ -16,6 +16,8 @@
package com.vaadin.tests.vaadincontext;
+import com.vaadin.annotations.BootstrapMod;
+import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Tag;
@@ -29,6 +31,9 @@ import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.UI;
+@BootstrapMod({
+ BootstrapModifyUI.BootstrapMod1.class,
+ BootstrapModifyUI.BootstrapMod2.class})
public class BootstrapModifyUI extends AbstractTestUI {
private static final String INSTALLED_ATRIBUTE_NAME = BootstrapModifyUI.class
.getName() + ".installed";
@@ -88,4 +93,29 @@ public class BootstrapModifyUI extends AbstractTestUI {
return Integer.valueOf(9274);
}
+ public static class BootstrapMod1 implements BootstrapListener {
+ @Override
+ public void modifyBootstrapFragment(BootstrapFragmentResponse response) {
+
+ }
+
+ @Override
+ public void modifyBootstrapPage(BootstrapPageResponse response) {
+ Document document = response.getDocument();
+ document.head().appendElement("bootstrap-1");
+ }
+ }
+
+ public static class BootstrapMod2 implements BootstrapListener {
+ @Override
+ public void modifyBootstrapFragment(BootstrapFragmentResponse response) {
+
+ }
+
+ @Override
+ public void modifyBootstrapPage(BootstrapPageResponse response) {
+ Document document = response.getDocument();
+ document.head().appendElement("bootstrap-2");
+ }
+ }
}