diff --git a/src/main/java/org/codelibs/fess/app/web/base/FessSearchAction.java b/src/main/java/org/codelibs/fess/app/web/base/FessSearchAction.java index d08616ba7..565a9eb61 100644 --- a/src/main/java/org/codelibs/fess/app/web/base/FessSearchAction.java +++ b/src/main/java/org/codelibs/fess/app/web/base/FessSearchAction.java @@ -119,7 +119,8 @@ public abstract class FessSearchAction extends FessBaseAction { runtime.registerData("osddLink", openSearchHelper.hasOpenSearchFile()); - final List> labelTypeItems = labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH); + final List> labelTypeItems = labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH, + request.getLocale() == null ? Locale.ROOT : request.getLocale()); runtime.registerData("labelTypeItems", labelTypeItems); runtime.registerData("displayLabelTypeItems", labelTypeItems != null && !labelTypeItems.isEmpty()); @@ -158,7 +159,8 @@ public abstract class FessSearchAction extends FessBaseAction { } // label - final List> labelTypeItems = labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH); + final List> labelTypeItems = labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH, + request.getLocale() == null ? Locale.ROOT : request.getLocale()); if (!labelTypeItems.isEmpty() && !form.fields.containsKey(FessSearchAction.LABEL_FIELD)) { final String[] defaultLabelValues = fessConfig.getDefaultLabelValues(getUserBean()); diff --git a/src/main/java/org/codelibs/fess/app/web/search/SearchAction.java b/src/main/java/org/codelibs/fess/app/web/search/SearchAction.java index e05d44dda..e7c92d158 100644 --- a/src/main/java/org/codelibs/fess/app/web/search/SearchAction.java +++ b/src/main/java/org/codelibs/fess/app/web/search/SearchAction.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -157,8 +158,8 @@ public class SearchAction extends FessSearchAction { form.q = renderData.getSearchQuery(); } renderData.register(data); - RenderDataUtil.register(data, "displayQuery", - getDisplayQuery(form, labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH))); + RenderDataUtil.register(data, "displayQuery", getDisplayQuery(form, labelTypeHelper + .getLabelTypeItemList(SearchRequestType.SEARCH, request.getLocale() == null ? Locale.ROOT : request.getLocale()))); createPagingQuery(form); final String[] relatedContents = relatedContentHelper.getRelatedContents(form.getQuery()); RenderDataUtil.register(data, "relatedContents", relatedContents); diff --git a/src/main/java/org/codelibs/fess/es/config/exentity/LabelType.java b/src/main/java/org/codelibs/fess/es/config/exentity/LabelType.java index ee4a58153..4810422ea 100644 --- a/src/main/java/org/codelibs/fess/es/config/exentity/LabelType.java +++ b/src/main/java/org/codelibs/fess/es/config/exentity/LabelType.java @@ -15,7 +15,10 @@ */ package org.codelibs.fess.es.config.exentity; +import java.util.Locale; + import org.codelibs.fess.es.config.bsentity.BsLabelType; +import org.codelibs.fess.util.ComponentUtil; /** * @author FreeGen @@ -23,6 +26,7 @@ import org.codelibs.fess.es.config.bsentity.BsLabelType; public class LabelType extends BsLabelType { private static final long serialVersionUID = 1L; + private Locale locale; public String getId() { return asDocMeta().id(); @@ -40,6 +44,16 @@ public class LabelType extends BsLabelType { asDocMeta().version(version); } + public Locale getLocale() { + if (locale == null) { + if (getValue() == null) { + return Locale.ROOT; + } + locale = ComponentUtil.getFessConfig().getQueryLocaleFromName(getValue()); + } + return locale; + } + @Override public String toString() { return "LabelType [createdBy=" + createdBy + ", createdTime=" + createdTime + ", excludedPaths=" + excludedPaths diff --git a/src/main/java/org/codelibs/fess/helper/LabelTypeHelper.java b/src/main/java/org/codelibs/fess/helper/LabelTypeHelper.java index 3f8f4875d..356d76324 100644 --- a/src/main/java/org/codelibs/fess/helper/LabelTypeHelper.java +++ b/src/main/java/org/codelibs/fess/helper/LabelTypeHelper.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -73,12 +74,17 @@ public class LabelTypeHelper { item.setValue(labelType.getValue()); item.setPermissions(labelType.getPermissions()); item.setVirtualHost(labelType.getVirtualHost()); + item.setLocale(labelType.getLocale()); itemList.add(item); } labelTypeItemList = itemList; } public List> getLabelTypeItemList(final SearchRequestType searchRequestType) { + return getLabelTypeItemList(searchRequestType, Locale.ROOT); + } + + public List> getLabelTypeItemList(final SearchRequestType searchRequestType, final Locale requestLocale) { if (labelTypeItemList == null) { init(); } @@ -86,10 +92,12 @@ public class LabelTypeHelper { final String virtualHostKey = ComponentUtil.getVirtualHostHelper().getVirtualHostKey(); final List labelList; if (StringUtil.isBlank(virtualHostKey)) { - labelList = labelTypeItemList; - } else { labelList = - labelTypeItemList.stream().filter(item -> virtualHostKey.equals(item.getVirtualHost())).collect(Collectors.toList()); + labelTypeItemList.stream().filter(item -> matchLocale(requestLocale, item.getLocale())).collect(Collectors.toList()); + } else { + labelList = labelTypeItemList.stream() + .filter(item -> matchLocale(requestLocale, item.getLocale()) && virtualHostKey.equals(item.getVirtualHost())) + .collect(Collectors.toList()); } final List> itemList = new ArrayList<>(); @@ -121,6 +129,22 @@ public class LabelTypeHelper { return itemList; } + protected boolean matchLocale(final Locale requestLocale, final Locale targetLocale) { + if (targetLocale.equals(requestLocale) || targetLocale.equals(Locale.ROOT)) { + return true; + } + if (requestLocale == null) { + return false; + } + if (!requestLocale.getLanguage().equals(targetLocale.getLanguage())) { + return false; + } + if (targetLocale.getCountry().length() > 0 && !requestLocale.getCountry().equals(targetLocale.getCountry())) { + return false; + } + return true; + } + public Set getMatchedLabelValueSet(final String path) { if (labelTypePatternList == null) { synchronized (this) { @@ -169,6 +193,8 @@ public class LabelTypeHelper { private String virtualHost; + private Locale locale; + public String getLabel() { return label; } @@ -200,6 +226,14 @@ public class LabelTypeHelper { public void setVirtualHost(final String virtualHost) { this.virtualHost = virtualHost; } + + public Locale getLocale() { + return locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } } public static class LabelTypePattern { diff --git a/src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java b/src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java index 1411367b6..1bf45d60f 100644 --- a/src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java +++ b/src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java @@ -1000,7 +1000,7 @@ public interface FessProp { String getQueryLanguageMapping(); - default String[] normalizeQueryLanguages(final String[] langs) { + default Map getQueryLanguageMappingMap() { @SuppressWarnings("unchecked") Map params = (Map) propMap.get(QUERY_LANGUAGE_MAPPING); if (params == null) { @@ -1013,7 +1013,11 @@ public interface FessProp { }).collect(Collectors.toMap(Pair::getFirst, Pair::getSecond))); propMap.put(QUERY_LANGUAGE_MAPPING, params); } - final Map mapping = params; + return params; + } + + default String[] normalizeQueryLanguages(final String[] langs) { + final Map mapping = getQueryLanguageMappingMap(); return stream(langs).get(stream -> stream.map(s -> { if (StringUtil.isBlank(s)) { return null; @@ -1060,6 +1064,29 @@ public interface FessProp { }).toArray(n -> new String[n])); } + default Locale getQueryLocaleFromName(final String name) { + if (name == null) { + return Locale.ROOT; + } + final String value = name.toLowerCase(Locale.ROOT); + final Map mapping = getQueryLanguageMappingMap(); + for (final String key : mapping.keySet()) { + if (value.endsWith("_" + key.toLowerCase(Locale.ROOT))) { + final String[] values = key.split("_"); + if (values.length == 1) { + return new Locale(values[0]); + } + if (values.length == 2) { + return new Locale(values[0], values[1]); + } + if (values.length == 3) { + return new Locale(values[0], values[1], values[2]); + } + } + } + return Locale.ROOT; + } + String getSupportedUploadedFiles(); default boolean isSupportedUploadedFile(final String name) { diff --git a/src/test/java/org/codelibs/fess/helper/LabelTypeHelperTest.java b/src/test/java/org/codelibs/fess/helper/LabelTypeHelperTest.java new file mode 100644 index 000000000..2461899a5 --- /dev/null +++ b/src/test/java/org/codelibs/fess/helper/LabelTypeHelperTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2021 CodeLibs Project and the Others. + * + * 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 org.codelibs.fess.helper; + +import java.util.Locale; + +import org.codelibs.fess.unit.UnitFessTestCase; + +public class LabelTypeHelperTest extends UnitFessTestCase { + + private LabelTypeHelper labelTypeHelper; + + @Override + public void setUp() throws Exception { + super.setUp(); + labelTypeHelper = new LabelTypeHelper(); + } + + public void test_matchLocale() { + assertFalse(labelTypeHelper.matchLocale(Locale.ENGLISH, Locale.JAPANESE)); + assertFalse(labelTypeHelper.matchLocale(Locale.SIMPLIFIED_CHINESE, Locale.TRADITIONAL_CHINESE)); + + assertTrue(labelTypeHelper.matchLocale(null, Locale.ROOT)); + assertTrue(labelTypeHelper.matchLocale(Locale.ENGLISH, Locale.ROOT)); + assertTrue(labelTypeHelper.matchLocale(Locale.ROOT, Locale.ROOT)); + assertTrue(labelTypeHelper.matchLocale(Locale.ENGLISH, Locale.ENGLISH)); + assertTrue(labelTypeHelper.matchLocale(Locale.JAPAN, Locale.JAPANESE)); + assertTrue(labelTypeHelper.matchLocale(Locale.SIMPLIFIED_CHINESE, Locale.CHINESE)); + assertTrue(labelTypeHelper.matchLocale(Locale.TRADITIONAL_CHINESE, Locale.CHINESE)); + } +} diff --git a/src/test/java/org/codelibs/fess/mylasta/direction/FessPropTest.java b/src/test/java/org/codelibs/fess/mylasta/direction/FessPropTest.java index baec77802..0d38b6680 100644 --- a/src/test/java/org/codelibs/fess/mylasta/direction/FessPropTest.java +++ b/src/test/java/org/codelibs/fess/mylasta/direction/FessPropTest.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; +import java.util.Locale; import org.codelibs.core.io.FileUtil; import org.codelibs.core.misc.DynamicProperties; @@ -215,6 +216,24 @@ public class FessPropTest extends UnitFessTestCase { assertArrays(new String[] { "zh-tw" }, fessConfig.normalizeQueryLanguages(new String[] { "zh_TW" })); } + public void test_getQueryLocaleFromName() { + FessProp.propMap.clear(); + FessConfig fessConfig = new FessConfig.SimpleImpl() { + @Override + public String getQueryLanguageMapping() { + return "ja=ja\nzh_cn=zh-cn\nzh_TW=zh-tw\nzh=zh-cn"; + } + }; + + assertEquals(Locale.ROOT, fessConfig.getQueryLocaleFromName(null)); + assertEquals(Locale.ROOT, fessConfig.getQueryLocaleFromName("")); + assertEquals(Locale.ROOT, fessConfig.getQueryLocaleFromName("ja")); + assertEquals(Locale.JAPANESE, fessConfig.getQueryLocaleFromName("test_ja")); + assertEquals(Locale.CHINESE, fessConfig.getQueryLocaleFromName("test_zh")); + assertEquals(Locale.SIMPLIFIED_CHINESE, fessConfig.getQueryLocaleFromName("test_zh_cn")); + assertEquals(Locale.TRADITIONAL_CHINESE, fessConfig.getQueryLocaleFromName("test_zh_TW")); + } + private void assertArrays(final String[] expected, final String[] actual) { Arrays.sort(expected); Arrays.sort(actual);