aboutsummaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/server/LocaleService.java
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/com/vaadin/server/LocaleService.java')
-rw-r--r--server/src/com/vaadin/server/LocaleService.java211
1 files changed, 211 insertions, 0 deletions
diff --git a/server/src/com/vaadin/server/LocaleService.java b/server/src/com/vaadin/server/LocaleService.java
new file mode 100644
index 0000000000..347c4da5c6
--- /dev/null
+++ b/server/src/com/vaadin/server/LocaleService.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2000-2013 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.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.logging.Logger;
+
+import com.vaadin.shared.ui.ui.UIState.LocaleData;
+import com.vaadin.shared.ui.ui.UIState.LocaleServiceState;
+import com.vaadin.ui.UI;
+
+/**
+ * Server side service which handles locale and the transmission of locale date
+ * to the client side LocaleService.
+ *
+ * @since 7.1
+ * @author Vaadin Ltd
+ */
+public class LocaleService {
+
+ private UI ui;
+
+ private LocaleServiceState state;
+
+ /**
+ * Creates a LocaleService bound to the given UI
+ *
+ * @since 7.1
+ * @param ui
+ * The UI which owns the LocaleService
+ */
+ public LocaleService(UI ui, LocaleServiceState state) {
+ this.ui = ui;
+ this.state = state;
+ }
+
+ /**
+ * Retrieves the UI this service is bound to
+ *
+ * @since 7.1
+ * @return the UI for this service
+ */
+ public UI getUI() {
+ return ui;
+ }
+
+ /**
+ * Adds a locale to be sent to the client (browser) for date and time entry
+ * etc. All locale specific information is derived from server-side
+ * {@link Locale} instances and sent to the client when needed, eliminating
+ * the need to use the {@link Locale} class and all the framework behind it
+ * on the client.
+ *
+ * @param locale
+ * The locale which is required on the client side
+ */
+ public void addLocale(Locale locale) {
+ for (LocaleData data : getState(false).localeData) {
+ if (data.name.equals(locale.toString())) {
+ // Already there
+ return;
+ }
+ }
+
+ getState(true).localeData.add(createLocaleData(locale));
+ }
+
+ /**
+ * Returns the state for this service
+ * <p>
+ * The state is transmitted inside the UI state rather than as an individual
+ * entity.
+ * </p>
+ *
+ * @since 7.1
+ * @param markAsDirty
+ * true to mark the state as dirty
+ * @return a LocaleServiceState object that can be read in any case and
+ * modified if markAsDirty is true
+ */
+ private LocaleServiceState getState(boolean markAsDirty) {
+ if (markAsDirty) {
+ getUI().markAsDirty();
+ }
+
+ return state;
+ }
+
+ /**
+ * Creates a LocaleData instance for transportation to the client
+ *
+ * @since 7.1
+ * @param locale
+ * The locale for which to create a LocaleData object
+ * @return A LocaleData object with information about the given locale
+ */
+ protected LocaleData createLocaleData(Locale locale) {
+ LocaleData localeData = new LocaleData();
+ localeData.name = locale.toString();
+
+ final DateFormatSymbols dfs = new DateFormatSymbols(locale);
+ localeData.shortMonthNames = dfs.getShortMonths();
+ localeData.monthNames = dfs.getMonths();
+ // Client expects 0 based indexing, DateFormatSymbols use 1 based
+ localeData.shortDayNames = new String[7];
+ localeData.dayNames = new String[7];
+ String[] sDayNames = dfs.getShortWeekdays();
+ String[] lDayNames = dfs.getWeekdays();
+ for (int i = 0; i < 7; i++) {
+ localeData.shortDayNames[i] = sDayNames[i + 1];
+ localeData.dayNames[i] = lDayNames[i + 1];
+ }
+
+ /*
+ * First day of week (0 = sunday, 1 = monday)
+ */
+ final java.util.Calendar cal = new GregorianCalendar(locale);
+ localeData.firstDayOfWeek = cal.getFirstDayOfWeek() - 1;
+
+ /*
+ * Date formatting (MM/DD/YYYY etc.)
+ */
+
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(
+ DateFormat.SHORT, DateFormat.SHORT, locale);
+ if (!(dateFormat instanceof SimpleDateFormat)) {
+ getLogger().warning(
+ "Unable to get default date pattern for locale "
+ + locale.toString());
+ dateFormat = new SimpleDateFormat();
+ }
+ final String df = ((SimpleDateFormat) dateFormat).toPattern();
+
+ int timeStart = df.indexOf("H");
+ if (timeStart < 0) {
+ timeStart = df.indexOf("h");
+ }
+ final int ampm_first = df.indexOf("a");
+ // E.g. in Korean locale AM/PM is before h:mm
+ // TODO should take that into consideration on client-side as well,
+ // now always h:mm a
+ if (ampm_first > 0 && ampm_first < timeStart) {
+ timeStart = ampm_first;
+ }
+ // Hebrew locale has time before the date
+ final boolean timeFirst = timeStart == 0;
+ String dateformat;
+ if (timeFirst) {
+ int dateStart = df.indexOf(' ');
+ if (ampm_first > dateStart) {
+ dateStart = df.indexOf(' ', ampm_first);
+ }
+ dateformat = df.substring(dateStart + 1);
+ } else {
+ dateformat = df.substring(0, timeStart - 1);
+ }
+
+ localeData.dateFormat = dateformat.trim();
+
+ /*
+ * Time formatting (24 or 12 hour clock and AM/PM suffixes)
+ */
+ final String timeformat = df.substring(timeStart, df.length());
+ /*
+ * Doesn't return second or milliseconds.
+ *
+ * We use timeformat to determine 12/24-hour clock
+ */
+ final boolean twelve_hour_clock = timeformat.indexOf("a") > -1;
+ // TODO there are other possibilities as well, like 'h' in french
+ // (ignore them, too complicated)
+ final String hour_min_delimiter = timeformat.indexOf(".") > -1 ? "."
+ : ":";
+ // outWriter.print("\"tf\":\"" + timeformat + "\",");
+ localeData.twelveHourClock = twelve_hour_clock;
+ localeData.hourMinuteDelimiter = hour_min_delimiter;
+ if (twelve_hour_clock) {
+ final String[] ampm = dfs.getAmPmStrings();
+ localeData.am = ampm[0];
+ localeData.pm = ampm[1];
+ }
+
+ return localeData;
+ }
+
+ private static Logger getLogger() {
+ return Logger.getLogger(LocaleService.class.getName());
+ }
+
+}