001/* 002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Sun Seng David TAN (a.k.a. sunix) <[email protected]> 018 * Stephane Lacoin at Nuxeo (aka matic) <[email protected]> 019 */ 020package org.nuxeo.ecm.webapp.locale; 021 022import java.io.Serializable; 023import java.util.Iterator; 024import java.util.Locale; 025 026import javax.faces.context.FacesContext; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.jboss.seam.Component; 031import org.jboss.seam.ScopeType; 032import org.jboss.seam.annotations.In; 033import org.jboss.seam.annotations.Name; 034import org.jboss.seam.annotations.Observer; 035import org.jboss.seam.annotations.Scope; 036import org.jboss.seam.annotations.Startup; 037import org.jboss.seam.contexts.Contexts; 038import org.jboss.seam.international.LocaleSelector; 039import org.jboss.seam.international.TimeZoneSelector; 040import org.nuxeo.ecm.core.api.CoreSession; 041import org.nuxeo.ecm.core.api.DocumentModel; 042import org.nuxeo.ecm.platform.web.common.locale.LocaleProvider; 043import org.nuxeo.ecm.webapp.helpers.EventNames; 044import org.nuxeo.runtime.api.Framework; 045 046/** 047 * Initialize the locale when the user session is entered. Enables client to send their timezone id through AJAX (not 048 * yet implemented). 049 * 050 * @since 5.6 051 */ 052@Name("clientLocaleInitializer") 053@Scope(ScopeType.SESSION) 054@Startup 055public class LocaleStartup implements Serializable { 056 057 private static final long serialVersionUID = 1L; 058 059 public static final Log log = LogFactory.getLog(LocaleStartup.class); 060 061 public static LocaleStartup instance() { 062 if (!Contexts.isSessionContextActive()) { 063 return null; 064 } 065 return (LocaleStartup) Component.getInstance(LocaleStartup.class, ScopeType.SESSION); 066 } 067 068 @In(create = true) 069 protected CoreSession documentManager; 070 071 protected String tzId; 072 073 public String getTzId() { 074 return tzId; 075 } 076 077 public void setTzId(String id) { 078 tzId = id; 079 } 080 081 @Observer(EventNames.USER_SESSION_STARTED) 082 public void handleUserSessionStarted(CoreSession session) { 083 setupTimeZone(session); 084 setupLocale(session); 085 } 086 087 /** 088 * Getting the timezone from the cookies and initialize Seam timezone. The nxtimezone.js contains methods to set the 089 * cookie with the browser timezone. 090 */ 091 public void setupTimeZone(CoreSession session) { 092 // Not using LocaleProvider to get persisted timezone because it is too 093 // hard to make it works with OpenSocialGadgets. 094 // and changing a timezone for a Date in javascript is not trivial. 095 TimeZoneSelector tzSelector = TimeZoneSelector.instance(); 096 tzSelector.setCookieEnabled(true); 097 tzSelector.initTimeZone(); 098 } 099 100 public void setupLocale(CoreSession session) { 101 Locale locale = Framework.getService(LocaleProvider.class).getLocale(session); 102 setupLocale(locale); 103 } 104 105 /** 106 * @since 5.9.5 107 */ 108 public void setupLocale(DocumentModel userProfileDoc) { 109 Locale locale = Framework.getService(LocaleProvider.class).getLocale(userProfileDoc); 110 setupLocale(locale); 111 } 112 113 protected void setupLocale(Locale locale) { 114 FacesContext ctx = FacesContext.getCurrentInstance(); 115 if (locale == null && ctx != null) { 116 log.debug("Locale not set, falling back to request locale"); 117 locale = ctx.getExternalContext().getRequestLocale(); 118 } 119 if (locale == null && ctx != null) { 120 log.debug("Locale not set, falling back to default JSF locale"); 121 locale = ctx.getApplication().getDefaultLocale(); 122 } 123 if (locale == null) { 124 log.debug("Locale not set, falling back to default locale"); 125 locale = Locale.getDefault(); 126 } 127 LocaleSelector localeSelector = LocaleSelector.instance(); 128 // check if locale is accepted for setup 129 boolean set = false; 130 if (ctx != null) { 131 Locale jsfDefault = ctx.getApplication().getDefaultLocale(); 132 if (jsfDefault != null && jsfDefault.equals(locale)) { 133 set = true; 134 } else { 135 Iterator<Locale> it = ctx.getApplication().getSupportedLocales(); 136 while (it.hasNext()) { 137 Locale current = it.next(); 138 if (current.equals(locale)) { 139 set = true; 140 break; 141 } 142 } 143 } 144 } 145 if (!set) { 146 if (log.isDebugEnabled()) { 147 log.debug( 148 "Locale was not set to '" + locale + "' as it could not be validated as a supported language."); 149 } 150 } else { 151 localeSelector.setLocale(locale); 152 localeSelector.setCookieEnabled(true); 153 localeSelector.select(); 154 } 155 } 156 157}