From 6337f8f8ccb88014f7a3d269332661ec8183b758 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Fri, 5 Oct 2012 10:32:48 +0300 Subject: [PATCH] Add SystemMessagesProvider for getting messages for a Locale (#4127) Also add an internal helper for finding the most suitable Locale based on the currently available information. Change-Id: Ie9893db4be5ace7b0d60c030b7ca383359500525 --- .../server/AbstractCommunicationManager.java | 6 ++- .../com/vaadin/server/BootstrapHandler.java | 6 ++- .../server/DefaultSystemMessagesProvider.java | 50 ++++++++++++++++++ .../vaadin/server/ServletPortletHelper.java | 50 ++++++++++++++++++ .../vaadin/server/SystemMessagesProvider.java | 45 ++++++++++++++++ .../src/com/vaadin/server/VaadinPortlet.java | 4 +- .../vaadin/server/VaadinPortletService.java | 5 -- .../src/com/vaadin/server/VaadinService.java | 52 +++++++++++++++++-- .../src/com/vaadin/server/VaadinServlet.java | 18 +++++-- .../vaadin/server/VaadinServletService.java | 5 -- 10 files changed, 219 insertions(+), 22 deletions(-) create mode 100644 server/src/com/vaadin/server/DefaultSystemMessagesProvider.java create mode 100644 server/src/com/vaadin/server/SystemMessagesProvider.java diff --git a/server/src/com/vaadin/server/AbstractCommunicationManager.java b/server/src/com/vaadin/server/AbstractCommunicationManager.java index 19b53c8a7a..0a3b18b86b 100644 --- a/server/src/com/vaadin/server/AbstractCommunicationManager.java +++ b/server/src/com/vaadin/server/AbstractCommunicationManager.java @@ -593,7 +593,8 @@ public abstract class AbstractCommunicationManager implements Serializable { if (!handleVariables(request, response, callback, session, uI)) { // var inconsistency; the client is probably out-of-sync - SystemMessages ci = response.getService().getSystemMessages(); + SystemMessages ci = response.getService().getSystemMessages( + uI.getLocale()); String msg = ci.getOutOfSyncMessage(); String cap = ci.getOutOfSyncCaption(); if (msg != null || cap != null) { @@ -1049,7 +1050,8 @@ public abstract class AbstractCommunicationManager implements Serializable { } } - SystemMessages ci = request.getService().getSystemMessages(); + SystemMessages ci = request.getService().getSystemMessages( + ui.getLocale()); // meta instruction for client to enable auto-forward to // sessionExpiredURL after timer expires. diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index e10351b4ad..c08d3bdbb1 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -430,8 +431,11 @@ public abstract class BootstrapHandler implements RequestHandler { appConfig.put("initialParams", parameterMap); + // Use locale from session if set, else from the request + Locale locale = ServletPortletHelper.findLocale(null, + context.getSession(), context.getRequest()); // Get system messages - SystemMessages systemMessages = vaadinService.getSystemMessages(); + SystemMessages systemMessages = vaadinService.getSystemMessages(locale); if (systemMessages != null) { // Write the CommunicationError -message to client JSONObject comErrMsg = new JSONObject(); diff --git a/server/src/com/vaadin/server/DefaultSystemMessagesProvider.java b/server/src/com/vaadin/server/DefaultSystemMessagesProvider.java new file mode 100644 index 0000000000..08042d3848 --- /dev/null +++ b/server/src/com/vaadin/server/DefaultSystemMessagesProvider.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012 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.server; + +import java.util.Locale; + +/** + * System messages provider using the built-in default system messages. This + * singleton is accessed using {@link #get()}. + * + * @author Vaadin Ltd + * @since 7.0.0 + */ +public class DefaultSystemMessagesProvider implements SystemMessagesProvider { + + private static final DefaultSystemMessagesProvider instance = new DefaultSystemMessagesProvider(); + + private DefaultSystemMessagesProvider() { + // Singleton + } + + @Override + public SystemMessages getSystemMessages(Locale locale) { + return ServletPortletHelper.DEFAULT_SYSTEM_MESSAGES; + } + + /** + * Gets the instance. + * + * @return the default system messages provider. + */ + public static SystemMessagesProvider get() { + return instance; + } + +} diff --git a/server/src/com/vaadin/server/ServletPortletHelper.java b/server/src/com/vaadin/server/ServletPortletHelper.java index 2611183b23..ab03e0cc06 100644 --- a/server/src/com/vaadin/server/ServletPortletHelper.java +++ b/server/src/com/vaadin/server/ServletPortletHelper.java @@ -1,10 +1,12 @@ package com.vaadin.server; import java.io.Serializable; +import java.util.Locale; import java.util.Properties; import com.vaadin.LegacyApplication; import com.vaadin.shared.ApplicationConstants; +import com.vaadin.ui.Component; import com.vaadin.ui.UI; /* @@ -173,4 +175,52 @@ class ServletPortletHelper implements Serializable { } } + /** + * Helper to find the most most suitable Locale. These potential sources are + * checked in order until a Locale is found: + *
    + *
  1. The passed component (or UI) if not null
  2. + *
  3. {@link UI#getCurrent()} if defined
  4. + *
  5. The passed session if not null
  6. + *
  7. {@link VaadinServiceSession#getCurrent()} if defined
  8. + *
  9. The passed request if not null
  10. + *
  11. {@link VaadinService#getCurrentRequest()} if defined
  12. + *
  13. {@link Locale#getDefault()}
  14. + *
+ */ + static Locale findLocale(Component component, VaadinServiceSession session, + VaadinRequest request) { + if (component == null) { + component = UI.getCurrent(); + } + if (component != null) { + Locale locale = component.getLocale(); + if (locale != null) { + return locale; + } + } + + if (session == null) { + session = VaadinServiceSession.getCurrent(); + } + if (session != null) { + Locale locale = session.getLocale(); + if (locale != null) { + return locale; + } + } + + if (request == null) { + request = VaadinService.getCurrentRequest(); + } + if (request != null) { + Locale locale = request.getLocale(); + if (locale != null) { + return locale; + } + } + + return Locale.getDefault(); + } + } diff --git a/server/src/com/vaadin/server/SystemMessagesProvider.java b/server/src/com/vaadin/server/SystemMessagesProvider.java new file mode 100644 index 0000000000..82d1014b9f --- /dev/null +++ b/server/src/com/vaadin/server/SystemMessagesProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012 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.server; + +import java.io.Serializable; +import java.util.Locale; + +import com.vaadin.ui.UI; + +/** + * Gives out system messages based on Locale. Registered using + * {@link VaadinService#setSystemMessagesProvider(SystemMessagesProvider)}. + * + * @author Vaadin Ltd + * @since 7.0.0 + */ +public interface SystemMessagesProvider extends Serializable { + /** + * Gets the system messages to use in the given context. Locale is the only + * piece of information guaranteed to be available, but in most cases some + * or all of {@link VaadinService#getCurrent()}, + * {@link VaadinService#getCurrentRequest()}, + * {@link VaadinServiceSession#getCurrent()} and {@link UI#getCurrent()} can + * also be used to find more information to help the decision. + * + * @param locale + * the desired locale of the system messages + * @return a system messages object + */ + public SystemMessages getSystemMessages(Locale locale); +} diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java index 231a463222..95178ade17 100644 --- a/server/src/com/vaadin/server/VaadinPortlet.java +++ b/server/src/com/vaadin/server/VaadinPortlet.java @@ -627,7 +627,9 @@ public class VaadinPortlet extends GenericPortlet implements Constants { // if this was an UIDL request, response UIDL back to client if (getRequestType(request) == RequestType.UIDL) { - SystemMessages ci = getService().getSystemMessages(); + SystemMessages ci = getService().getSystemMessages( + ServletPortletHelper.findLocale(null, vaadinSession, + request)); criticalNotification(request, response, ci.getInternalErrorCaption(), ci.getInternalErrorMessage(), null, ci.getInternalErrorURL()); diff --git a/server/src/com/vaadin/server/VaadinPortletService.java b/server/src/com/vaadin/server/VaadinPortletService.java index aa81c39d9d..ac48900945 100644 --- a/server/src/com/vaadin/server/VaadinPortletService.java +++ b/server/src/com/vaadin/server/VaadinPortletService.java @@ -111,11 +111,6 @@ public class VaadinPortletService extends VaadinService { return getPortlet().getPortletContext().getMimeType(resourceName); } - @Override - public SystemMessages getSystemMessages() { - return ServletPortletHelper.DEFAULT_SYSTEM_MESSAGES; - } - @Override public File getBaseDirectory() { PortletContext context = getPortlet().getPortletContext(); diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index c56d6caeb5..28684ec8dc 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -77,6 +77,9 @@ public abstract class VaadinService implements Serializable { private final EventRouter eventRouter = new EventRouter(); + private SystemMessagesProvider systemMessagesProvider = DefaultSystemMessagesProvider + .get(); + /** * Creates a new vaadin service based on a deployment configuration * @@ -206,11 +209,54 @@ public abstract class VaadinService implements Serializable { } /** - * Gets the system messages object + * Sets the system messages provider to use for getting system messages to + * display to users of this service. + * + * @see #getSystemMessagesProvider() + * + * @param systemMessagesProvider + * the system messages provider; null is not + * allowed. + */ + public void setSystemMessagesProvider( + SystemMessagesProvider systemMessagesProvider) { + if (systemMessagesProvider == null) { + throw new IllegalArgumentException( + "SystemMessagesProvider can not be null."); + } + this.systemMessagesProvider = systemMessagesProvider; + } + + /** + * Gets the system messages provider currently defined for this service. + *

+ * By default, the {@link DefaultSystemMessagesProvider} which always + * provides the built-in default {@link SystemMessages} is used. + *

* - * @return the system messages object + * @see #setSystemMessagesProvider(SystemMessagesProvider) + * @see SystemMessagesProvider + * @see SystemMessages + * + * @return the system messages provider; not null + */ + public SystemMessagesProvider getSystemMessagesProvider() { + return systemMessagesProvider; + } + + /** + * Gets the system message to use for a specific locale. This method may + * also be implemented to use information from current instances of various + * objects, which means that this method might return different values for + * the same locale under different circumstances. + * + * @param locale + * the desired locale for the system messages + * @return the system messages to use */ - public abstract SystemMessages getSystemMessages(); + public SystemMessages getSystemMessages(Locale locale) { + return getSystemMessagesProvider().getSystemMessages(locale); + } /** * Returns the context base directory. diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java index eb375e0b92..bd724aad63 100644 --- a/server/src/com/vaadin/server/VaadinServlet.java +++ b/server/src/com/vaadin/server/VaadinServlet.java @@ -378,8 +378,8 @@ public class VaadinServlet extends HttpServlet implements Constants { // This can be removed if cookieless mode (#3228) is supported if (request.getRequestedSessionId() == null) { // User has cookies disabled - SystemMessages systemMessages = getService() - .getSystemMessages(); + SystemMessages systemMessages = getService().getSystemMessages( + ServletPortletHelper.findLocale(null, null, request)); criticalNotification(request, response, systemMessages.getCookiesDisabledCaption(), systemMessages.getCookiesDisabledMessage(), null, @@ -535,7 +535,9 @@ public class VaadinServlet extends HttpServlet implements Constants { Throwable e) throws IOException, ServletException { // if this was an UIDL request, response UIDL back to client if (getRequestType(request) == RequestType.UIDL) { - SystemMessages ci = getService().getSystemMessages(); + SystemMessages ci = getService().getSystemMessages( + ServletPortletHelper.findLocale(null, vaadinSession, + request)); criticalNotification(request, response, ci.getInternalErrorCaption(), ci.getInternalErrorMessage(), null, ci.getInternalErrorURL()); @@ -610,7 +612,8 @@ public class VaadinServlet extends HttpServlet implements Constants { } try { - SystemMessages ci = getService().getSystemMessages(); + SystemMessages ci = getService().getSystemMessages( + ServletPortletHelper.findLocale(null, null, request)); RequestType requestType = getRequestType(request); if (requestType == RequestType.UIDL) { /* @@ -655,7 +658,12 @@ public class VaadinServlet extends HttpServlet implements Constants { } try { - SystemMessages ci = getService().getSystemMessages(); + /* + * We might have a UI, but we don't want to leak any information in + * this case so just use the info provided in the request. + */ + SystemMessages ci = getService().getSystemMessages( + request.getLocale()); RequestType requestType = getRequestType(request); if (requestType == RequestType.UIDL) { // send uidl redirect diff --git a/server/src/com/vaadin/server/VaadinServletService.java b/server/src/com/vaadin/server/VaadinServletService.java index d746ee2303..b8af3b13fb 100644 --- a/server/src/com/vaadin/server/VaadinServletService.java +++ b/server/src/com/vaadin/server/VaadinServletService.java @@ -100,11 +100,6 @@ public class VaadinServletService extends VaadinService { return getServlet().getServletContext().getMimeType(resourceName); } - @Override - public SystemMessages getSystemMessages() { - return ServletPortletHelper.DEFAULT_SYSTEM_MESSAGES; - } - @Override public File getBaseDirectory() { final String realPath = VaadinServlet.getResourcePath( -- 2.39.5