diff options
author | elmot <elmot@vaadin.com> | 2016-02-29 10:00:00 +0200 |
---|---|---|
committer | elmot <elmot@vaadin.com> | 2016-03-02 14:57:30 +0200 |
commit | 46a4710095c00978f03007ac56bbdc513997a86e (patch) | |
tree | 126fa9a4149bc135c404aebb5b9449c0aae81f2d | |
parent | 83bffb42f708226f10ed92521cb6dcc124047a6c (diff) | |
download | vaadin-framework-46a4710095c00978f03007ac56bbdc513997a86e.tar.gz vaadin-framework-46a4710095c00978f03007ac56bbdc513997a86e.zip |
BootstrapListeners as an annotation
Change-Id: I695aad4150dca1f71424f41b5669e404efc71354
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"); + } + } } |