package org.vaadin.touchkit.settings; import java.io.Serializable; import java.util.ArrayList; import org.vaadin.touchkit.annotations.CacheManifestEnabled; import org.vaadin.touchkit.annotations.OfflineModeEnabled; import org.vaadin.touchkit.server.TouchKitServlet; import com.vaadin.server.BootstrapFragmentResponse; import com.vaadin.server.BootstrapListener; import com.vaadin.server.BootstrapPageResponse; import com.vaadin.server.CustomizedSystemMessages; import com.vaadin.server.ServiceException; import com.vaadin.server.SessionInitEvent; import com.vaadin.server.SessionInitListener; import com.vaadin.server.SystemMessages; import com.vaadin.server.SystemMessagesInfo; import com.vaadin.server.SystemMessagesProvider; import com.vaadin.server.VaadinService; import com.vaadin.server.VaadinServletService; /** * TouchKitSettings is a collection of tools that help modify various touch * device related settings on the html page. The class must be bound to * VaadinService and configured in an early phase to be functional. * <p> * This class should be instantiated by and used through the servlet class, * which is {@link TouchKitServlet} by default. */ @SuppressWarnings("serial") public class TouchKitSettings implements BootstrapListener, SessionInitListener, SystemMessagesProvider { /** * Interface to select different settings for different kind of devices * based on e.g. HTTP header inspection. */ interface SettingSelector<T> extends Serializable { /** * @param response * @return used settings or null if settings shouldn't be used for this * request. */ T select(BootstrapPageResponse response); } private ViewPortSettings defaultViewPortSettings; private ArrayList<SettingSelector<ViewPortSettings>> selectorBasedViewPortSettings = new ArrayList<TouchKitSettings.SettingSelector<ViewPortSettings>>(); private WebAppSettings webAppSettings; private ApplicationIcons applicationIcons; private ApplicationCacheSettings applicationCacheSettings; /** * Creates and binds a TouchKitSettings instance to the * {@link VaadinService} instance, which is automatically fetched from a * thread local. */ public TouchKitSettings() { this(VaadinService.getCurrent()); } /** * Creates a new instance of TouchKitSettings and binds it to the given * {@link VaadinService}. * * @param vaadinService * the vaadin service to which the new instance should be bound. */ public TouchKitSettings(VaadinService vaadinService) { setViewPortSettings(new ViewPortSettings()); /* * WP8 needs device-width and maximum scale to work like ios (with * default settings). Without these custom values pixel size is huge in * landscape mode. With these values iphone5 goes to letter box when on * home screen. * * @viewport css rule will replace meta tags in the future and there is * a prefixed version in MobileIE10, but it is buggy (landscape mode * don't change "device-width"). */ final ViewPortSettings ieViewPortSettings = new ViewPortSettings(); ieViewPortSettings.setViewPortWidth("device-width"); ieViewPortSettings.setViewPortMaximumScale(1f); addViewPortSettings(new SettingSelector<ViewPortSettings>() { @Override public ViewPortSettings select(BootstrapPageResponse response) { String ua = response.getRequest().getHeader("User-Agent"); if (ua != null && ua.contains("IEMobile")) { return ieViewPortSettings; } return null; } }); setWebAppSettings(new WebAppSettings()); setApplicationIcons(new ApplicationIcons()); setApplicationCacheSettings(new ApplicationCacheSettings()); vaadinService.addSessionInitListener(this); vaadinService.setSystemMessagesProvider(this); } /** * Selects viewport settings to be used for given bootstrap * request/response. * * @param response * @return The {@link ViewPortSettings} */ private ViewPortSettings selectViewPortSettings( BootstrapPageResponse response) { for (SettingSelector<ViewPortSettings> s : selectorBasedViewPortSettings) { ViewPortSettings selected = s.select(response); if (selected != null) { return selected; } } return defaultViewPortSettings; } /** * @return The {@link ViewPortSettings} used by default. */ public ViewPortSettings getViewPortSettings() { return defaultViewPortSettings; } /** * @return The {@link WebAppSettings} */ public WebAppSettings getWebAppSettings() { return webAppSettings; } /** * @return The {@link ApplicationIcons} */ public ApplicationIcons getApplicationIcons() { return applicationIcons; } @Override public void modifyBootstrapFragment(BootstrapFragmentResponse response) { // NOP no support for portlets currently } @Override public void modifyBootstrapPage(BootstrapPageResponse response) { ViewPortSettings viewPortSettings2 = selectViewPortSettings(response); if (viewPortSettings2 != null) { viewPortSettings2.modifyBootstrapPage(response); } if (getWebAppSettings() != null) { getWebAppSettings().modifyBootstrapPage(response); } if (getApplicationIcons() != null) { getApplicationIcons().modifyBootstrapPage(response); } if (getApplicationCacheSettings() != null) { OfflineModeEnabled offline = null; CacheManifestEnabled manifest = null; Class<?> clazz = response.getUiClass(); if (clazz != null) { offline = clazz.getAnnotation(OfflineModeEnabled.class); manifest = clazz.getAnnotation(CacheManifestEnabled.class); } if (response.getSession().getService() instanceof VaadinServletService) { clazz = ((VaadinServletService) response.getSession() .getService()).getServlet().getClass(); if (offline == null) { offline = clazz.getAnnotation(OfflineModeEnabled.class); } if (manifest == null) { manifest = clazz.getAnnotation(CacheManifestEnabled.class); } } getApplicationCacheSettings().setCacheManifestEnabled( manifest == null || manifest.value()); getApplicationCacheSettings().setOfflineModeEnabled( offline == null || offline.value()); getApplicationCacheSettings().modifyBootstrapPage(response); } } @Override public void sessionInit(SessionInitEvent event) throws ServiceException { event.getSession().addBootstrapListener(this); } /** * @return The {@link ApplicationCacheSettings} */ public ApplicationCacheSettings getApplicationCacheSettings() { return applicationCacheSettings; } /** * Sets the {@link ApplicationCacheSettings} instance to use. * * @param applicationCacheSettings * the {@link ApplicationCacheSettings} instance to use. */ public void setApplicationCacheSettings( ApplicationCacheSettings applicationCacheSettings) { this.applicationCacheSettings = applicationCacheSettings; } /** * Sets the {@link ApplicationIcons} instance to use. * * @param applicationIcons * the {@link ApplicationIcons} instance to use. */ public void setApplicationIcons(ApplicationIcons applicationIcons) { this.applicationIcons = applicationIcons; } /** * Sets the {@link ViewPortSettings} instance to use by default. * * @param viewPortSettings * the {@link ViewPortSettings} instance to use. * @see #addViewPortSettings(SettingSelector) */ public void setViewPortSettings(ViewPortSettings viewPortSettings) { defaultViewPortSettings = viewPortSettings; } /** * Adds a request dependent view port settings. If selector returns * settings, it will override default view port setting. * * @param viewPortSettingSelector */ public void addViewPortSettings( SettingSelector<ViewPortSettings> viewPortSettingSelector) { selectorBasedViewPortSettings.add(viewPortSettingSelector); } /** * Sets the {@link WebAppSettings} instance to use. * * @param iosWebAppSettings * the {@link WebAppSettings} instance to use. */ public void setWebAppSettings(WebAppSettings iosWebAppSettings) { webAppSettings = iosWebAppSettings; } @Override public SystemMessages getSystemMessages( SystemMessagesInfo systemMessagesInfo) { CustomizedSystemMessages customizedSystemMessages = new CustomizedSystemMessages(); customizedSystemMessages .setCommunicationErrorNotificationEnabled(false); customizedSystemMessages.setSessionExpiredNotificationEnabled(false); return customizedSystemMessages; } }