Skip to content
Permalink
Browse files

Fix an error when GN is deployed as ROOT context ("/") (#4358)

Fixes #4309. Fixes an `ArrayIndexOutOfBoundsException` that happened when
GeoNetwork is deployed with ROOT ("/") as context name.

It also fix a bug related to the wrong part of the URL being selected as
the locale used in the request.
  • Loading branch information
juanluisrp committed Jan 15, 2020
1 parent e2e0a21 commit efc50e5159f988e931428c7fc4f17ec1f81fb6b6
@@ -23,56 +23,80 @@

package org.fao.geonet.i18n;

import java.util.Locale;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.fao.geonet.NodeInfo;
import org.springframework.beans.propertyeditors.LocaleEditor;
import org.springframework.util.Assert;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/**
* Strongly based on LocaleChangeInterceptor from Spring
*
* @author delawen
*/
public class UrlLocaleChangeInterceptor extends HandlerInterceptorAdapter {
public static final Integer DEFAULT_URL_POSITION = 0;
public static final Integer DEFAULT_URL_POSITION = 2;
/**
* Indicates the position of the segment of the Url path that contains
* the language removing the context path. For example, if the request URL is
* /geonetwork/srv/eng/catalog.signin
* removing the servlet context results in
* /srv/eng/catalog.signin
* and urlPosition should be 2 to match the position or eng.
*/
private Integer urlPosition = DEFAULT_URL_POSITION;

/**
* Indicates the position of the segment of the Url path that contains
* the language removing the context path. For example, if the request URL is
* <code>/geonetwork/srv/eng/catalog.signin</code>
* removing the servlet context results in
* <code>/srv/eng/catalog.signin</code>
* and urlPosition should be 2 to match the position or eng.
*
* @param p the position of the URL path segment after the servlet context that contains the language.
*/
public void setUrlPosition(Integer p) {
Assert.isTrue(p > 0, "urlPosition must be greater than 0");
this.urlPosition = p;
}

@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws ServletException {
HttpServletResponse response, Object handler) {

String pathAfterContext = request.getRequestURI().substring(request.getContextPath().length());
String[] path = pathAfterContext.split("/");
// URL path contains the node id as the first part of the URL
// eg. /srv/eng/catalogue.search or /srv/api/...
if ((urlPosition >= path.length)
|| (path.length > 1 && NodeInfo.EXCLUDED_NODE_IDS.contains(path[1]))
|| path.length > 2 && "api".equals(path[2])) {
// matches URLs like /catalog/... /
return true;
}

String url = request.getRequestURI();
String[] path = url.split("/");
String newLocale = null;
Integer position = urlPosition;

if (path.length >= position) {
newLocale = path[position];
if (newLocale != null) {
LocaleResolver localeResolver = RequestContextUtils
.getLocaleResolver(request);
if (localeResolver == null) {
throw new IllegalStateException(
"No LocaleResolver found: not in a DispatcherServlet request?");
}
LocaleEditor localeEditor = new LocaleEditor();
localeEditor.setAsText(newLocale);
localeResolver.setLocale(request, response,
(Locale) localeEditor.getValue());
String localeCode = path[urlPosition];
if (localeCode != null) {
LocaleResolver localeResolver = RequestContextUtils
.getLocaleResolver(request);
if (localeResolver == null) {
throw new IllegalStateException(
"No LocaleResolver found: not in a DispatcherServlet request?");
}
LocaleEditor localeEditor = new LocaleEditor();
localeEditor.setAsText(localeCode);
localeResolver.setLocale(request, response,
(Locale) localeEditor.getValue());
}


// Proceed in any case.
return true;
}
@@ -64,7 +64,7 @@
<property name="paramName" value="\${language.default}"/>
</bean>
<bean id="urlLocaleChangeInterceptor" class="org.fao.geonet.i18n.UrlLocaleChangeInterceptor">
<property name="urlPosition" value="0"/>
<property name="urlPosition" value="2"/>
</bean>

<bean id="readWriteMvcInterceptor" class="jeeves.config.springutil.ReadOnlyMvcInterceptor"/>

0 comments on commit efc50e5

Please sign in to comment.
You can’t perform that action at this time.