diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index eebefc2410..c6901c9769 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -96,6 +96,10 @@ path + + + + true diff --git a/source/java/org/alfresco/web/app/servlet/AuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/AuthenticationFilter.java index cb4ed7b6db..0c0d1ac18f 100644 --- a/source/java/org/alfresco/web/app/servlet/AuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/AuthenticationFilter.java @@ -44,8 +44,8 @@ import org.alfresco.web.app.Application; * Servlet filter responsible for redirecting to the login page for the Web Client if the user * does not have a valid ticket. *

- * The current ticker is validated for each page request and the login page is shown if the - * ticker has expired. + * The current ticket is validated for each page request and the login page is shown if the + * ticket has expired. *

* Note that this filter is only active when the system is running in a servlet container - * the AlfrescoFacesPortlet will be used for a JSR-168 Portal environment. @@ -82,7 +82,6 @@ public class AuthenticationFilter implements Filter } else { - // authentication failed - so end servlet execution and redirect to login page // also save the requested URL so the login page knows where to redirect too later BaseServlet.redirectToLoginPage(httpReq, httpRes, context); @@ -90,6 +89,8 @@ public class AuthenticationFilter implements Filter } else { + BaseServlet.setLanguageFromRequestHeader(httpReq); + // continue filter chaining chain.doFilter(req, res); } diff --git a/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java b/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java index 4a7a6be679..f30ad84450 100644 --- a/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java +++ b/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java @@ -27,6 +27,7 @@ package org.alfresco.web.app.servlet; import java.io.IOException; import java.util.Enumeration; +import javax.faces.context.FacesContext; import javax.portlet.PortletSession; import javax.servlet.ServletContext; import javax.servlet.http.Cookie; @@ -50,6 +51,7 @@ import org.alfresco.service.cmr.security.PersonService; import org.alfresco.web.app.Application; import org.alfresco.web.bean.LoginBean; import org.alfresco.web.bean.repository.User; +import org.alfresco.web.config.ClientConfigElement; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.web.context.WebApplicationContext; @@ -180,9 +182,17 @@ public final class AuthenticationHelper // store the User object in the Session - the authentication servlet will then proceed session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user); - // Set the current locale - FacesHelper.getFacesContext(req, res, sc); - I18NUtil.setLocale(Application.getLanguage(req.getSession())); + // Set the current locale and language + FacesContext fc = FacesHelper.getFacesContext(req, res, sc); + if (Application.getClientConfig(fc).isLanguageSelect()) + { + I18NUtil.setLocale(Application.getLanguage(req.getSession())); + } + else + { + // Set the current thread locale (also for JSF context) + fc.getViewRoot().setLocale(BaseServlet.setLanguageFromRequestHeader(req)); + } // remove the session invalidated flag session.removeAttribute(AuthenticationHelper.SESSION_INVALIDATED); @@ -240,10 +250,18 @@ public final class AuthenticationHelper } // setup faces context - FacesHelper.getFacesContext(req, res, sc); + FacesContext fc = FacesHelper.getFacesContext(req, res, sc); - // Set the current locale - I18NUtil.setLocale(Application.getLanguage(req.getSession())); + // Set the current locale and language + if (Application.getClientConfig(fc).isLanguageSelect()) + { + I18NUtil.setLocale(Application.getLanguage(req.getSession())); + } + else + { + // Set the current thread locale (also for JSF context) + fc.getViewRoot().setLocale(BaseServlet.setLanguageFromRequestHeader(req)); + } if (loginBean != null && (loginBean.getUserPreferencesBean() != null)) { @@ -331,8 +349,18 @@ public final class AuthenticationHelper } // Set the current locale - FacesHelper.getFacesContext(httpRequest, httpResponse, context); - I18NUtil.setLocale(Application.getLanguage(httpRequest.getSession())); + FacesContext fc = FacesHelper.getFacesContext(httpRequest, httpResponse, context); + + // Set the current locale and language + if (Application.getClientConfig(fc).isLanguageSelect()) + { + I18NUtil.setLocale(Application.getLanguage(httpRequest.getSession())); + } + else + { + // Set the current thread locale (also for JSF context) + fc.getViewRoot().setLocale(BaseServlet.setLanguageFromRequestHeader(httpRequest)); + } return AuthenticationStatus.Success; } diff --git a/source/java/org/alfresco/web/app/servlet/BaseServlet.java b/source/java/org/alfresco/web/app/servlet/BaseServlet.java index 3775fe61a0..2fefb1e575 100644 --- a/source/java/org/alfresco/web/app/servlet/BaseServlet.java +++ b/source/java/org/alfresco/web/app/servlet/BaseServlet.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.StringTokenizer; @@ -52,6 +53,7 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.jsf.FacesContextUtils; +import org.alfresco.i18n.I18NUtil; import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; @@ -197,6 +199,28 @@ public abstract class BaseServlet extends HttpServlet } } + /** + * Apply Client and Repository language locale based on the 'Accept-Language' request header + */ + public static Locale setLanguageFromRequestHeader(HttpServletRequest req) + { + Locale locale = null; + + // set language locale from browser header + String acceptLang = req.getHeader("Accept-Language"); + if (acceptLang != null && acceptLang.length() != 0) + { + StringTokenizer t = new StringTokenizer(acceptLang, ",; "); + // get language and convert to java locale format + String language = t.nextToken().replace('-', '_'); + Application.setLanguage(req.getSession(), language); + locale = I18NUtil.parseLocale(language); + I18NUtil.setLocale(locale); + } + + return locale; + } + /** * Apply the headers required to disallow caching of the response in the browser */ diff --git a/source/java/org/alfresco/web/app/servlet/ExternalAccessServlet.java b/source/java/org/alfresco/web/app/servlet/ExternalAccessServlet.java index 8f444afe84..94f37a967b 100644 --- a/source/java/org/alfresco/web/app/servlet/ExternalAccessServlet.java +++ b/source/java/org/alfresco/web/app/servlet/ExternalAccessServlet.java @@ -212,15 +212,23 @@ public class ExternalAccessServlet extends BaseServlet } else if (OUTCOME_BROWSE.equals(outcome)) { - if (args != null && args.length >= 3) + NodeRef nodeRef = null; + + if (args.length != 0 && args[0].equals(WebDAVServlet.WEBDAV_PREFIX)) + { + nodeRef = resolveWebDAVPath(fc, args); + } + else if (args.length >= 3) { - NodeRef nodeRef = null; int offset = 0; offset = args.length - 3; StoreRef storeRef = new StoreRef(args[0+offset], args[1+offset]); nodeRef = new NodeRef(storeRef, args[2+offset]); - + } + + if (nodeRef != null) + { // check that the user has at least READ access - else redirect to the login page if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED) { diff --git a/source/java/org/alfresco/web/bean/LoginBean.java b/source/java/org/alfresco/web/bean/LoginBean.java index fd37eca781..d9e82003d2 100644 --- a/source/java/org/alfresco/web/bean/LoginBean.java +++ b/source/java/org/alfresco/web/bean/LoginBean.java @@ -201,6 +201,14 @@ public class LoginBean implements Serializable { return this.password; } + + /** + * @return true to display language selection, false to + */ + public boolean isLanguageSelect() + { + return Application.getClientConfig(FacesContext.getCurrentInstance()).isLanguageSelect(); + } // ------------------------------------------------------------------------------ diff --git a/source/java/org/alfresco/web/config/ClientConfigElement.java b/source/java/org/alfresco/web/config/ClientConfigElement.java index 0445d81305..a1cac32fe3 100644 --- a/source/java/org/alfresco/web/config/ClientConfigElement.java +++ b/source/java/org/alfresco/web/config/ClientConfigElement.java @@ -81,6 +81,8 @@ public class ClientConfigElement extends ConfigElementAdapter private int minPasswordLength = 3; private String breadcrumbMode = BREADCRUMB_PATH; private String cifsURLSuffix; + private boolean languageSelect = true; + /** * Default Constructor @@ -256,6 +258,11 @@ public class ClientConfigElement extends ConfigElementAdapter combinedElement.setBreadcrumbMode(newElement.getBreadcrumbMode()); } + if (newElement.isLanguageSelect() != combinedElement.isLanguageSelect()) + { + combinedElement.setLanguageSelect(newElement.isLanguageSelect()); + } + return combinedElement; } @@ -700,7 +707,7 @@ public class ClientConfigElement extends ConfigElementAdapter breadcrumbMode = mode; } } - + /** * Get the CIFs URL suffix * @@ -708,9 +715,9 @@ public class ClientConfigElement extends ConfigElementAdapter */ public final String getCifsURLSuffix() { - return cifsURLSuffix; + return cifsURLSuffix; } - + /** * Set the CIFS URL suffix * @@ -718,6 +725,23 @@ public class ClientConfigElement extends ConfigElementAdapter */ void setCifsURLSuffix(String suffix) { - cifsURLSuffix = suffix; + cifsURLSuffix = suffix; + } + + /** + * @return the language select flag - true to display language selection, false to + * get the language from the client browser locale instead + */ + public final boolean isLanguageSelect() + { + return this.languageSelect; + } + + /** + * @param value the language select flag + */ + /*package*/ void setLanguageSelect(boolean value) + { + this.languageSelect = value; } } diff --git a/source/java/org/alfresco/web/config/ClientElementReader.java b/source/java/org/alfresco/web/config/ClientElementReader.java index b3d82134a4..2546ac7f52 100644 --- a/source/java/org/alfresco/web/config/ClientElementReader.java +++ b/source/java/org/alfresco/web/config/ClientElementReader.java @@ -66,6 +66,8 @@ public class ClientElementReader implements ConfigElementReader public static final String ELEMENT_MINPASSWORDLENGTH = "password-min-length"; public static final String ELEMENT_BREADCRUMB_MODE = "breadcrumb-mode"; public static final String ELEMENT_CIFSURLSUFFIX = "cifs-url-suffix"; + public static final String ELEMENT_LANGUAGESELECT = "language-select"; + /** * @see org.alfresco.config.xml.elementreader.ConfigElementReader#parse(org.dom4j.Element) @@ -262,15 +264,24 @@ public class ClientElementReader implements ConfigElementReader { configElement.setBreadcrumbMode(breadcrumbMode.getTextTrim()); } - + // Get the CIFS URL suffix Element cifsSuffix = element.element(ELEMENT_CIFSURLSUFFIX); - if ( cifsSuffix != null) + if (cifsSuffix != null) { - String suffix = cifsSuffix.getTextTrim(); - if ( suffix.startsWith( ".") == false) - suffix = "." + suffix; - configElement.setCifsURLSuffix( suffix); + String suffix = cifsSuffix.getTextTrim(); + if (suffix.startsWith(".") == false) + { + suffix = "." + suffix; + } + configElement.setCifsURLSuffix( suffix); + } + + // get the language selection mode + Element langSelect = element.element(ELEMENT_LANGUAGESELECT); + if (langSelect != null) + { + configElement.setLanguageSelect(Boolean.parseBoolean(langSelect.getTextTrim())); } } diff --git a/source/java/org/alfresco/web/ui/common/PanelGenerator.java b/source/java/org/alfresco/web/ui/common/PanelGenerator.java index 04b5beae7f..244e83d570 100644 --- a/source/java/org/alfresco/web/ui/common/PanelGenerator.java +++ b/source/java/org/alfresco/web/ui/common/PanelGenerator.java @@ -108,6 +108,46 @@ public final class PanelGenerator out.write(";'>"); } + public static void generatePanelStartWithBgImg(final Writer out, + final String contextPath, final String panel, String bgColor) + throws IOException + { + out.write(""); + out.write(""); + + out.write(""); + + out.write(""); + + out.write("
"); + } + public static void generatePanelEnd(final Writer out, final String contextPath, final String panel) @@ -146,6 +186,40 @@ public final class PanelGenerator out.write("_09.gif' width='7' height='7' alt=''/>
"); } + public static void generatePanelEndWithBgImg(final Writer out, + final String contextPath, + final String panel) + throws IOException + { + out.write(""); + + out.write(""); + + out.write(""); + + out.write(""); +} + public static void generateTitledPanelMiddle(final Writer out, final String contextPath, final String titlePanel, diff --git a/source/web/images/filetypes/xdp.gif b/source/web/images/filetypes/xdp.gif new file mode 100644 index 0000000000..90435d2836 Binary files /dev/null and b/source/web/images/filetypes/xdp.gif differ diff --git a/source/web/images/filetypes/xdp.png b/source/web/images/filetypes/xdp.png new file mode 100644 index 0000000000..dd446a0946 Binary files /dev/null and b/source/web/images/filetypes/xdp.png differ diff --git a/source/web/images/filetypes32/jp2.gif b/source/web/images/filetypes32/jp2.gif new file mode 100644 index 0000000000..734fa7e125 Binary files /dev/null and b/source/web/images/filetypes32/jp2.gif differ diff --git a/source/web/images/filetypes32/jpe.gif b/source/web/images/filetypes32/jpe.gif new file mode 100644 index 0000000000..734fa7e125 Binary files /dev/null and b/source/web/images/filetypes32/jpe.gif differ diff --git a/source/web/images/filetypes32/jpeg.gif b/source/web/images/filetypes32/jpeg.gif new file mode 100644 index 0000000000..734fa7e125 Binary files /dev/null and b/source/web/images/filetypes32/jpeg.gif differ diff --git a/source/web/images/filetypes32/jpm.gif b/source/web/images/filetypes32/jpm.gif new file mode 100644 index 0000000000..734fa7e125 Binary files /dev/null and b/source/web/images/filetypes32/jpm.gif differ diff --git a/source/web/images/filetypes32/jpx.gif b/source/web/images/filetypes32/jpx.gif new file mode 100644 index 0000000000..734fa7e125 Binary files /dev/null and b/source/web/images/filetypes32/jpx.gif differ diff --git a/source/web/images/filetypes32/xdp.gif b/source/web/images/filetypes32/xdp.gif new file mode 100644 index 0000000000..39abbe1570 Binary files /dev/null and b/source/web/images/filetypes32/xdp.gif differ diff --git a/source/web/images/filetypes32/xdp.png b/source/web/images/filetypes32/xdp.png new file mode 100644 index 0000000000..6f39cac0f8 Binary files /dev/null and b/source/web/images/filetypes32/xdp.png differ diff --git a/source/web/images/filetypes64/jp2.png b/source/web/images/filetypes64/jp2.png new file mode 100644 index 0000000000..cf41baea75 Binary files /dev/null and b/source/web/images/filetypes64/jp2.png differ diff --git a/source/web/images/filetypes64/jpe.png b/source/web/images/filetypes64/jpe.png new file mode 100644 index 0000000000..cf41baea75 Binary files /dev/null and b/source/web/images/filetypes64/jpe.png differ diff --git a/source/web/images/filetypes64/jpeg.png b/source/web/images/filetypes64/jpeg.png new file mode 100644 index 0000000000..cf41baea75 Binary files /dev/null and b/source/web/images/filetypes64/jpeg.png differ diff --git a/source/web/images/filetypes64/jpm.png b/source/web/images/filetypes64/jpm.png new file mode 100644 index 0000000000..cf41baea75 Binary files /dev/null and b/source/web/images/filetypes64/jpm.png differ diff --git a/source/web/images/filetypes64/jpx.png b/source/web/images/filetypes64/jpx.png new file mode 100644 index 0000000000..cf41baea75 Binary files /dev/null and b/source/web/images/filetypes64/jpx.png differ diff --git a/source/web/images/filetypes64/xdp.png b/source/web/images/filetypes64/xdp.png new file mode 100644 index 0000000000..feed207408 Binary files /dev/null and b/source/web/images/filetypes64/xdp.png differ diff --git a/source/web/jsp/login.jsp b/source/web/jsp/login.jsp index ffed0cce18..1e3691bbfa 100644 --- a/source/web/jsp/login.jsp +++ b/source/web/jsp/login.jsp @@ -28,9 +28,12 @@ <%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> +<%@ page import="org.alfresco.web.app.servlet.BaseServlet" %> <%@ page import="org.alfresco.web.app.servlet.AuthenticationHelper" %> <%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> +<%@ page import="javax.faces.context.FacesContext" %> <%@ page import="javax.servlet.http.Cookie" %> +<%@ page import="java.util.Locale" %> <%@ page buffer="16kb" contentType="text/html;charset=UTF-8" %> <%@ page isELIgnored="false" %> @@ -55,6 +58,9 @@ session.setAttribute(AuthenticationHelper.SESSION_USERNAME, authCookie.getValue()); } } + + // setup system locale from the Accept-Language header value + Locale locale = BaseServlet.setLanguageFromRequestHeader(request); %> @@ -62,6 +68,13 @@ +<% + FacesContext fc = FacesContext.getCurrentInstance(); + + // set locale for JSF framework usage + fc.getViewRoot().setLocale(locale); +%> + <%-- load a bundle of properties I18N strings here --%> @@ -116,11 +129,11 @@ - : + <%-- language selection drop-down --%> - + diff --git a/source/web/jsp/users/user-console.jsp b/source/web/jsp/users/user-console.jsp index 125e1be957..aac62b57c8 100644 --- a/source/web/jsp/users/user-console.jsp +++ b/source/web/jsp/users/user-console.jsp @@ -120,9 +120,9 @@ - +