From 1f80469efe0ff9850dfab9ed358ede3be3069337 Mon Sep 17 00:00:00 2001
From: Shinsuke Sugaya <shinsuke@yahoo.co.jp>
Date: Sat, 22 Feb 2014 15:55:17 +0900
Subject: [PATCH] #116

---
 pom.xml                                       |  5 ++
 src/main/java/jp/sf/fess/Constants.java       |  4 +
 .../java/jp/sf/fess/action/IndexAction.java   | 55 +++++++++++++
 src/main/java/jp/sf/fess/form/IndexForm.java  |  2 +
 .../java/jp/sf/fess/helper/SystemHelper.java  | 75 +++++++++++++++++-
 .../sf/fess/helper/impl/QueryHelperImpl.java  | 23 ++----
 src/main/resources/app.dicon                  |  8 +-
 src/main/resources/application.properties     |  4 +-
 src/main/resources/application_ja.properties  |  2 +
 src/main/resources/fess.dicon                 |  6 +-
 src/main/webapp/WEB-INF/view/error/header.jsp | 75 ++++++++++--------
 src/main/webapp/WEB-INF/view/header.jsp       | 77 +++++++++++--------
 src/main/webapp/WEB-INF/view/index.jsp        | 77 +++++++++++--------
 13 files changed, 291 insertions(+), 122 deletions(-)

diff --git a/pom.xml b/pom.xml
index ae7dea6eb..120de07d8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -449,6 +449,11 @@
       <artifactId>standard</artifactId>
       <version>1.1.2</version>
     </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>16.0.1</version>
+    </dependency>
     <dependency>
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
diff --git a/src/main/java/jp/sf/fess/Constants.java b/src/main/java/jp/sf/fess/Constants.java
index 21ce6ad3c..5d7121544 100644
--- a/src/main/java/jp/sf/fess/Constants.java
+++ b/src/main/java/jp/sf/fess/Constants.java
@@ -166,6 +166,8 @@ public class Constants extends CoreLibConstants {
 
     public static final String NOTIFICATION_TO_PROPERTY = "notification.to";
 
+    public static final String USE_BROWSER_LOCALE_FOR_SEARCH_PROPERTY = "search.browser.locale";
+
     public static final String AUTH_CIPHER = "authenticationCipher";
 
     public static final String RETURN_PATH = "jp.sf.fess.ReturnPath";
@@ -325,4 +327,6 @@ public class Constants extends CoreLibConstants {
 
     public static final String DCF = "dcf";
 
+    public static final String ALL_LANGUAGES = "all";
+
 }
diff --git a/src/main/java/jp/sf/fess/action/IndexAction.java b/src/main/java/jp/sf/fess/action/IndexAction.java
index c9e368c42..6aee8b254 100644
--- a/src/main/java/jp/sf/fess/action/IndexAction.java
+++ b/src/main/java/jp/sf/fess/action/IndexAction.java
@@ -30,6 +30,7 @@ import java.util.Arrays;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
@@ -96,6 +97,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class IndexAction {
+
     private static final Logger logger = LoggerFactory
             .getLogger(IndexAction.class);
 
@@ -191,6 +193,8 @@ public class IndexAction {
 
     public List<Map<String, String>> labelTypeItems;
 
+    public List<Map<String, String>> langItems;
+
     public String errorMessage;
 
     protected String pagingQuery = null;
@@ -218,6 +222,27 @@ public class IndexAction {
             if (StringUtil.isNotBlank(indexForm.sort)) {
                 buf.append("&sort=").append(S2Functions.u(indexForm.sort));
             }
+            if (indexForm.lang != null) {
+                final Set<String> langSet = new HashSet<String>();
+                for (final String lang : indexForm.lang) {
+                    if (StringUtil.isNotBlank(lang) && lang.length() < 1000) {
+                        if (Constants.ALL_LANGUAGES.equals(lang)) {
+                            langSet.clear();
+                            break;
+                        }
+                        final String normalizeLang = systemHelper
+                                .normalizeLang(lang);
+                        if (normalizeLang != null) {
+                            langSet.add(normalizeLang);
+                        }
+                    }
+                }
+                if (!langSet.isEmpty()) {
+                    for (final String lang : langSet) {
+                        buf.append("&lang=").append(S2Functions.u(lang));
+                    }
+                }
+            }
             if (!indexForm.fields.isEmpty()) {
                 for (final Map.Entry<String, String[]> entry : indexForm.fields
                         .entrySet()) {
@@ -773,6 +798,30 @@ public class IndexAction {
                 }
             }
         }
+        if (indexForm.lang != null) {
+            for (final String lang : indexForm.lang) {
+                if (StringUtil.isNotBlank(lang) && lang.length() < 1000) {
+                    final String normalizeLang = systemHelper
+                            .normalizeLang(lang);
+                    if (normalizeLang != null) {
+                        queryBuf.append(' ').append(systemHelper.langField)
+                                .append(':').append(normalizeLang);
+                    }
+                }
+            }
+        } else if (Constants.TRUE.equals(crawlerProperties.getProperty(
+                Constants.USE_BROWSER_LOCALE_FOR_SEARCH_PROPERTY,
+                Constants.FALSE))) {
+            final Locale locale = request.getLocale();
+            if (locale != null) {
+                final String normalizeLang = systemHelper.normalizeLang(locale
+                        .getLanguage());
+                if (normalizeLang != null) {
+                    queryBuf.append(' ').append(systemHelper.langField)
+                            .append(':').append(normalizeLang);
+                }
+            }
+        }
 
         final String query = queryBuf.toString().trim();
 
@@ -1069,6 +1118,12 @@ public class IndexAction {
             }
         }
 
+        Locale locale = request.getLocale();
+        if (locale == null) {
+            locale = Locale.ENGLISH;
+        }
+        langItems = systemHelper.getLanguageItems(locale);
+
         searchLogSupport = Constants.TRUE.equals(crawlerProperties.getProperty(
                 Constants.SEARCH_LOG_PROPERTY, Constants.TRUE));
         favoriteSupport = Constants.TRUE.equals(crawlerProperties.getProperty(
diff --git a/src/main/java/jp/sf/fess/form/IndexForm.java b/src/main/java/jp/sf/fess/form/IndexForm.java
index 4de37a093..8d01cf20e 100644
--- a/src/main/java/jp/sf/fess/form/IndexForm.java
+++ b/src/main/java/jp/sf/fess/form/IndexForm.java
@@ -48,6 +48,8 @@ public class IndexForm implements Serializable {
     @IntegerType
     public String num;
 
+    public String[] lang;
+
     @Maxbytelength(maxbytelength = 1000)
     public String queryId;
 
diff --git a/src/main/java/jp/sf/fess/helper/SystemHelper.java b/src/main/java/jp/sf/fess/helper/SystemHelper.java
index 0e5ad8119..e905bdf08 100644
--- a/src/main/java/jp/sf/fess/helper/SystemHelper.java
+++ b/src/main/java/jp/sf/fess/helper/SystemHelper.java
@@ -22,6 +22,7 @@ import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.sql.Timestamp;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -30,6 +31,8 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import jp.sf.fess.Constants;
@@ -38,6 +41,7 @@ import jp.sf.fess.db.exentity.RoleType;
 import jp.sf.fess.service.RoleTypeService;
 import jp.sf.fess.util.ResourceUtil;
 
+import org.apache.commons.lang.LocaleUtils;
 import org.apache.commons.lang.StringUtils;
 import org.codelibs.solr.lib.SolrGroup;
 import org.codelibs.solr.lib.policy.QueryType;
@@ -47,11 +51,16 @@ import org.seasar.framework.container.annotation.tiger.InitMethod;
 import org.seasar.framework.util.FileUtil;
 import org.seasar.framework.util.StringUtil;
 import org.seasar.robot.util.CharUtil;
+import org.seasar.struts.util.MessageResourcesUtil;
 import org.seasar.struts.util.RequestUtil;
 import org.seasar.struts.util.ServletContextUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
 public class SystemHelper implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -125,6 +134,13 @@ public class SystemHelper implements Serializable {
 
     public String langField = "lang_s";
 
+    protected String[] supportedLanguages = new String[] { "ar", "bg", "ca",
+            "da", "de", "el", "en", "es", "eu", "fa", "fi", "fr", "ga", "gl",
+            "hi", "hu", "hy", "id", "it", "ja", "lv", "ko", "nl", "no", "pt",
+            "ro", "ru", "sv", "th", "tr", "zh", "zh_CN", "zh_TW" };
+
+    protected LoadingCache<String, List<Map<String, String>>> langItemsCache;
+
     @InitMethod
     public void init() {
         final File[] files = ResourceUtil.getJarFiles(launcherFileNamePrefix);
@@ -176,6 +192,35 @@ public class SystemHelper implements Serializable {
                         + jnlpTemplateFile.getAbsolutePath(), e);
             }
         }
+
+        langItemsCache = CacheBuilder.newBuilder().maximumSize(20)
+                .expireAfterAccess(1, TimeUnit.HOURS)
+                .build(new CacheLoader<String, List<Map<String, String>>>() {
+                    @Override
+                    public List<Map<String, String>> load(final String key)
+                            throws Exception {
+                        final Locale displayLocale = LocaleUtils.toLocale(key);
+                        final List<Map<String, String>> langItems = new ArrayList<>(
+                                supportedLanguages.length);
+                        final String msg = MessageResourcesUtil.getMessage(
+                                displayLocale, "labels.allLanguages");
+                        final Map<String, String> defaultMap = new HashMap<>(2);
+                        defaultMap.put(Constants.ITEM_LABEL, msg);
+                        defaultMap.put(Constants.ITEM_VALUE, "all");
+                        langItems.add(defaultMap);
+
+                        for (final String lang : supportedLanguages) {
+                            final Locale locale = LocaleUtils.toLocale(lang);
+                            final String label = locale
+                                    .getDisplayName(displayLocale);
+                            final Map<String, String> map = new HashMap<>(2);
+                            map.put(Constants.ITEM_LABEL, label);
+                            map.put(Constants.ITEM_VALUE, lang);
+                            langItems.add(map);
+                        }
+                        return langItems;
+                    }
+                });
     }
 
     public String getUsername() {
@@ -447,9 +492,37 @@ public class SystemHelper implements Serializable {
             }
         }
         if (buf.length() > 0) {
-            return buf.toString();
+            final String lang = buf.toString();
+            for (final String supportedLang : supportedLanguages) {
+                if (supportedLang.equalsIgnoreCase(lang)) {
+                    return supportedLang;
+                }
+            }
         }
         return null;
     }
 
+    public List<Map<String, String>> getLanguageItems(final Locale locale) {
+        try {
+            return langItemsCache.get(locale.toString());
+        } catch (final ExecutionException e) {
+            final List<Map<String, String>> langItems = new ArrayList<>(
+                    supportedLanguages.length);
+            final String msg = MessageResourcesUtil.getMessage(locale,
+                    "labels.allLanguages");
+            final Map<String, String> defaultMap = new HashMap<>(2);
+            defaultMap.put(Constants.ITEM_LABEL, msg);
+            defaultMap.put(Constants.ITEM_VALUE, "all");
+            langItems.add(defaultMap);
+            return langItems;
+        }
+    }
+
+    public String[] getSupportedLanguages() {
+        return supportedLanguages;
+    }
+
+    public void setSupportedLanguages(final String[] supportedLanguages) {
+        this.supportedLanguages = supportedLanguages;
+    }
 }
diff --git a/src/main/java/jp/sf/fess/helper/impl/QueryHelperImpl.java b/src/main/java/jp/sf/fess/helper/impl/QueryHelperImpl.java
index 3aff0be00..92a6fcb1a 100644
--- a/src/main/java/jp/sf/fess/helper/impl/QueryHelperImpl.java
+++ b/src/main/java/jp/sf/fess/helper/impl/QueryHelperImpl.java
@@ -40,6 +40,7 @@ import jp.sf.fess.entity.SearchQuery.SortField;
 import jp.sf.fess.helper.BrowserTypeHelper;
 import jp.sf.fess.helper.QueryHelper;
 import jp.sf.fess.helper.RoleQueryHelper;
+import jp.sf.fess.helper.SystemHelper;
 import jp.sf.fess.util.QueryUtil;
 import jp.sf.fess.util.SearchParamMap;
 
@@ -84,13 +85,16 @@ public class QueryHelperImpl implements QueryHelper, Serializable {
     @Resource
     protected RoleQueryHelper roleQueryHelper;
 
+    @Resource
+    protected SystemHelper systemHelper;
+
     protected Set<String> apiResponseFieldSet;
 
     protected String[] responseFields = new String[] { "id", "docId", "score",
             "boost", "contentLength", "host", "site", "lastModified",
             "mimetype", "filetype_s", "created", TTTLE_FIELD, "digest", "url",
             "clickCount_l_x_dv", "favoriteCount_l_x_dv", "screenshot_s_s",
-            "cid_s_s" };
+            "cid_s_s", "lang_s" };
 
     protected String[] responseDocValuesFields = new String[] {
             "clickCount_l_x_dv", "favoriteCount_l_x_dv" };
@@ -100,7 +104,7 @@ public class QueryHelperImpl implements QueryHelper, Serializable {
     protected String[] searchFields = new String[] { "url", "docId", "host",
             TTTLE_FIELD, CONTENT_FIELD, "contentLength", "lastModified",
             "mimetype", "filetype_s", LABEL_FIELD, "segment",
-            "clickCount_l_x_dv", "favoriteCount_l_x_dv", INURL_FIELD };
+            "clickCount_l_x_dv", "favoriteCount_l_x_dv", INURL_FIELD, "lang_s" };
 
     protected String[] facetFields = new String[] { "url", "host", TTTLE_FIELD,
             CONTENT_FIELD, "contentLength", "lastModified", "mimetype",
@@ -134,11 +138,6 @@ public class QueryHelperImpl implements QueryHelper, Serializable {
 
     protected String additionalGeoQuery;
 
-    protected String[] supportedLanguages = new String[] { "ar", "bg", "ca",
-            "cz", "da", "de", "el", "es", "eu", "fa", "fi", "fr", "ga", "gl",
-            "hi", "hu", "hy", "id", "it", "ja", "lv", "ko", "nl", "no", "pt",
-            "ro", "ru", "sv", "th", "tr", "zh", "zh_CN", "zh_TW" };
-
     protected Map<String, String> fieldLanguageMap = new HashMap<String, String>();
 
     protected int maxSearchResultOffset = 100000;
@@ -914,6 +913,8 @@ public class QueryHelperImpl implements QueryHelper, Serializable {
     }
 
     protected String getQueryLanguage() {
+        final String[] supportedLanguages = systemHelper
+                .getSupportedLanguages();
         if (supportedLanguages.length == 0) {
             return null;
         }
@@ -1288,14 +1289,6 @@ public class QueryHelperImpl implements QueryHelper, Serializable {
         this.additionalGeoQuery = additionalGeoQuery;
     }
 
-    public String[] getSupportedLanguages() {
-        return supportedLanguages;
-    }
-
-    public void setSupportedLanguages(final String[] supportedLanguages) {
-        this.supportedLanguages = supportedLanguages;
-    }
-
     public void addFieldLanguage(final String lang, final String fieldLang) {
         fieldLanguageMap.put(lang, fieldLang);
     }
diff --git a/src/main/resources/app.dicon b/src/main/resources/app.dicon
index 41b0ae88b..2cf97e79b 100644
--- a/src/main/resources/app.dicon
+++ b/src/main/resources/app.dicon
@@ -76,13 +76,13 @@
 		<property name="additionalGeoQuery">"location_i_i:1"</property>
 		<property name="responseFields">new String[]{"id", "docId", "score", "boost",
             "contentLength", "host", "site", "lastModified", "mimetype", "filetype_s",
-            "created", "title", "digest", "url", "screenshot_s_s", "cid_s_s"}</property>
+            "created", "title", "digest", "url", "screenshot_s_s", "cid_s_s", "lang_s"}</property>
 		<property name="responseDocValuesFields">new String[]{
             "clickCount_l_x_dv", "favoriteCount_l_x_dv"}</property>
 		<property name="highlightingFields">new String[]{"digest", "cache" }</property>
 		<property name="searchFields">new String[]{"url", "docId", "host", 
             "title", "content", "contentLength", "lastModified", "mimetype", "filetype_s",
-            "label", "segment" }</property>
+            "label", "segment", "lang_s" }</property>
 		<property name="facetFields">new String[]{"url", "host", 
             "title", "content", "contentLength", "lastModified", "mimetype", "filetype_s",
             "label", "segment" }</property>
@@ -100,10 +100,6 @@
 			<arg>"debug.explain.structured"</arg>
 			<arg>"true"</arg>
 		</initMethod>
-		<property name="supportedLanguages">new String[] { "ar", "bg", "ca",
-            "cz", "da", "de", "el", "es", "eu", "fa", "fi", "fr", "ga", "gl",
-            "hi", "hu", "hy", "id", "it", "ja", "lv", "ko", "nl", "no", "pt",
-            "ro", "ru", "sv", "th", "tr", "zh", "zh_CN", "zh_TW" }</property>
 		<initMethod name="addDefaultSortField">
 			<arg>"score"</arg>
 			<arg>"desc"</arg>
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 25d25d99f..712b07af0 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -274,6 +274,7 @@ labels.webApiJson=JSON Response
 labels.webApiXml=XML Response
 labels.webConfigId=ID
 labels.webConfigName=Config Name
+labels.allLanguages=All Languages
 
 # view/common/common.jsp
 
@@ -399,7 +400,8 @@ labels.password=Password
 labels.login=Login
 labels.login.footer_copyright=Copyright(C) 2009-2014 CodeLibs Project. All Rights Reserved.
 labels.login_title=Login
-labels.index_label=Label
+labels.index_label=Labels
+labels.index_lang=Languages
 labels.index_sort=Sort
 labels.index_num=Results per page
 
diff --git a/src/main/resources/application_ja.properties b/src/main/resources/application_ja.properties
index 475a733d2..73d25d48d 100644
--- a/src/main/resources/application_ja.properties
+++ b/src/main/resources/application_ja.properties
@@ -274,6 +274,7 @@ labels.webApiJson=JSON\u5fdc\u7b54
 labels.webApiXml=XML\u5fdc\u7b54
 labels.webConfigId=ID
 labels.webConfigName=\u8a2d\u5b9a\u540d
+labels.allLanguages=\u3059\u3079\u3066\u306e\u8a00\u8a9e
 
 # view/common/common.jsp
 
@@ -420,6 +421,7 @@ labels.index_hotkeywords_title=\u6ce8\u76ee\u30ad\u30fc\u30ef\u30fc\u30c9
 labels.index_osdd_title=Fess Search
 labels.index_form_option_btn=\u30aa\u30d7\u30b7\u30e7\u30f3
 labels.index_label=\u30e9\u30d9\u30eb
+labels.index_lang=\u8a00\u8a9e
 labels.index_sort=\u30bd\u30fc\u30c8
 labels.index_num=\u8868\u793a\u4ef6\u6570
 labels.index_help=\u30d8\u30eb\u30d7
diff --git a/src/main/resources/fess.dicon b/src/main/resources/fess.dicon
index 26e1b1db1..6231e7496 100644
--- a/src/main/resources/fess.dicon
+++ b/src/main/resources/fess.dicon
@@ -28,7 +28,11 @@
 		<property name="javaCommandPath">"java"</property>
 		<property name="filterPathEncoding">"UTF-8"</property>
 		<property name="useOwnTmpDir">true</property>
-		<property name="baseHelpLink">"http://fess.codelibs.org/{lang}/8.0/admin/"</property>
+		<property name="baseHelpLink">"http://fess.codelibs.org/{lang}/9.0/admin/"</property>
+		<property name="supportedLanguages">new String[] { "ar", "bg", "ca",
+            "cz", "da", "de", "el", "en", "es", "eu", "fa", "fi", "fr", "ga", "gl",
+            "hi", "hu", "hy", "id", "it", "ja", "lv", "ko", "nl", "no", "pt",
+            "ro", "ru", "sv", "th", "tr", "zh", "zh_CN", "zh_TW" }</property>
 		-->
 		<property name="logFilePath">@System@getProperty("fess.log.file").replaceAll(".out", "_crawler.out")</property>
         <property name="crawlerJavaOptions">new String[] {
diff --git a/src/main/webapp/WEB-INF/view/error/header.jsp b/src/main/webapp/WEB-INF/view/error/header.jsp
index 2534cc343..3ddb36f5f 100755
--- a/src/main/webapp/WEB-INF/view/error/header.jsp
+++ b/src/main/webapp/WEB-INF/view/error/header.jsp
@@ -30,26 +30,24 @@
 		</div>
 		<div class="modal-body">
 			<fieldset>
-				<c:if test="${displayLabelTypeItems}">
-					<div class="clearfix">
-						<label for="contentLabelType"><bean:message
-								key="labels.index_label" /></label>
-						<div class="input">
-							<html:select property="fields.label" styleId="contentLabelType"
-								multiple="true" styleClass="span4">
-								<c:forEach var="item" items="${labelTypeItems}">
-									<html:option value="${f:u(item.value)}">
-														${f:h(item.label)}
-													</html:option>
-								</c:forEach>
-							</html:select>
-							<span id="contentLabelTypeNoneSelectedText" class="hide"><bean:message
-									key="labels.search_result_noneselect_label" /></span> <span
-								id="contentLabelTypeSelectedText" class="hide"><bean:message
-									key="labels.search_result_select_label" /></span>
-						</div>
+				<div class="clearfix">
+					<label for="contentNum"><bean:message
+							key="labels.index_num" /></label>
+					<div class="input">
+						<html:select property="num" styleId="contentNum"
+							styleClass="span4" style="display:block;">
+							<option value="">
+								<bean:message key="labels.search_result_select_num" />
+							</option>
+							<html:option value="10">10</html:option>
+							<html:option value="20">20</html:option>
+							<html:option value="30">30</html:option>
+							<html:option value="40">40</html:option>
+							<html:option value="50">50</html:option>
+							<html:option value="100">100</html:option>
+						</html:select>
 					</div>
-				</c:if>
+				</div>
 				<div class="clearfix">
 					<label for="contentSort"><bean:message
 							key="labels.index_sort" /></label>
@@ -81,23 +79,36 @@
 					</div>
 				</div>
 				<div class="clearfix">
-					<label for="contentNum"><bean:message
-							key="labels.index_num" /></label>
+					<label for="contentLang"><bean:message
+							key="labels.index_lang" /></label>
 					<div class="input">
-						<html:select property="num" styleId="contentNum"
-							styleClass="span4" style="display:block;">
-							<option value="">
-								<bean:message key="labels.search_result_select_num" />
-							</option>
-							<html:option value="10">10</html:option>
-							<html:option value="20">20</html:option>
-							<html:option value="30">30</html:option>
-							<html:option value="40">40</html:option>
-							<html:option value="50">50</html:option>
-							<html:option value="100">100</html:option>
+						<html:select property="lang"
+							styleId="langSearchOption" multiple="true"
+							styleClass="span4">
+							<c:forEach var="item" items="${langItems}">
+								<html:option value="${f:u(item.value)}">
+													${f:h(item.label)}
+												</html:option>
+							</c:forEach>
 						</html:select>
 					</div>
 				</div>
+				<c:if test="${displayLabelTypeItems}">
+					<div class="clearfix">
+						<label for="contentLabelType"><bean:message
+								key="labels.index_label" /></label>
+						<div class="input">
+							<html:select property="fields.label" styleId="contentLabelType"
+								multiple="true" styleClass="span4">
+								<c:forEach var="item" items="${labelTypeItems}">
+									<html:option value="${f:u(item.value)}">
+														${f:h(item.label)}
+													</html:option>
+								</c:forEach>
+							</html:select>
+						</div>
+					</div>
+				</c:if>
 			</fieldset>
 		</div>
 		<div class="modal-footer">
diff --git a/src/main/webapp/WEB-INF/view/header.jsp b/src/main/webapp/WEB-INF/view/header.jsp
index 748f32e31..edcb6067d 100755
--- a/src/main/webapp/WEB-INF/view/header.jsp
+++ b/src/main/webapp/WEB-INF/view/header.jsp
@@ -33,27 +33,24 @@ ${fe:facetForm()}${fe:mltForm()}${fe:geoForm()}
 		</div>
 		<div class="modal-body">
 			<fieldset>
-				<c:if test="${displayLabelTypeItems}">
-					<div class="clearfix">
-						<label for="contentLabelType"><bean:message
-								key="labels.index_label" /></label>
-						<div class="input">
-							<html:select property="fields.label"
-								styleId="labelTypeSearchOption" multiple="true"
-								styleClass="span4">
-								<c:forEach var="item" items="${labelTypeItems}">
-									<html:option value="${f:u(item.value)}">
-														${f:h(item.label)}
-													</html:option>
-								</c:forEach>
-							</html:select>
-							<span id="contentLabelTypeNoneSelectedText" class="hide"><bean:message
-									key="labels.search_result_noneselect_label" /></span> <span
-								id="contentLabelTypeSelectedText" class="hide"><bean:message
-									key="labels.search_result_select_label" /></span>
-						</div>
+				<div class="clearfix">
+					<label for="contentNum"><bean:message
+							key="labels.index_num" /></label>
+					<div class="input">
+						<html:select property="num" styleId="numSearchOption"
+							styleClass="span4" style="display:block;">
+							<option value="">
+								<bean:message key="labels.search_result_select_num" />
+							</option>
+							<html:option value="10">10</html:option>
+							<html:option value="20">20</html:option>
+							<html:option value="30">30</html:option>
+							<html:option value="40">40</html:option>
+							<html:option value="50">50</html:option>
+							<html:option value="100">100</html:option>
+						</html:select>
 					</div>
-				</c:if>
+				</div>
 				<div class="clearfix">
 					<label for="contentSort"><bean:message
 							key="labels.index_sort" /></label>
@@ -102,23 +99,37 @@ ${fe:facetForm()}${fe:mltForm()}${fe:geoForm()}
 					</div>
 				</div>
 				<div class="clearfix">
-					<label for="contentNum"><bean:message
-							key="labels.index_num" /></label>
+					<label for="contentLang"><bean:message
+							key="labels.index_lang" /></label>
 					<div class="input">
-						<html:select property="num" styleId="numSearchOption"
-							styleClass="span4" style="display:block;">
-							<option value="">
-								<bean:message key="labels.search_result_select_num" />
-							</option>
-							<html:option value="10">10</html:option>
-							<html:option value="20">20</html:option>
-							<html:option value="30">30</html:option>
-							<html:option value="40">40</html:option>
-							<html:option value="50">50</html:option>
-							<html:option value="100">100</html:option>
+						<html:select property="lang"
+							styleId="langSearchOption" multiple="true"
+							styleClass="span4">
+							<c:forEach var="item" items="${langItems}">
+								<html:option value="${f:u(item.value)}">
+													${f:h(item.label)}
+												</html:option>
+							</c:forEach>
 						</html:select>
 					</div>
 				</div>
+				<c:if test="${displayLabelTypeItems}">
+					<div class="clearfix">
+						<label for="contentLabelType"><bean:message
+								key="labels.index_label" /></label>
+						<div class="input">
+							<html:select property="fields.label"
+								styleId="labelTypeSearchOption" multiple="true"
+								styleClass="span4">
+								<c:forEach var="item" items="${labelTypeItems}">
+									<html:option value="${f:u(item.value)}">
+														${f:h(item.label)}
+													</html:option>
+								</c:forEach>
+							</html:select>
+						</div>
+					</div>
+				</c:if>
 			</fieldset>
 		</div>
 		<div class="modal-footer">
diff --git a/src/main/webapp/WEB-INF/view/index.jsp b/src/main/webapp/WEB-INF/view/index.jsp
index 80f27dc0d..03a078617 100644
--- a/src/main/webapp/WEB-INF/view/index.jsp
+++ b/src/main/webapp/WEB-INF/view/index.jsp
@@ -85,27 +85,24 @@
 						</div>
 						<div class="modal-body">
 							<fieldset>
-								<c:if test="${displayLabelTypeItems}">
-									<div class="clearfix">
-										<label for="contentLabelType"><bean:message
-												key="labels.index_label" /></label>
-										<div class="input">
-											<html:select property="fields.label"
-												styleId="labelTypeSearchOption" multiple="true"
-												styleClass="span4">
-												<c:forEach var="item" items="${labelTypeItems}">
-													<html:option value="${f:u(item.value)}">
-														${f:h(item.label)}
-													</html:option>
-												</c:forEach>
-											</html:select>
-											<span id="contentLabelTypeNoneSelectedText" class="hide"><bean:message
-													key="labels.search_result_noneselect_label" /></span> <span
-												id="contentLabelTypeSelectedText" class="hide"><bean:message
-													key="labels.search_result_select_label" /></span>
-										</div>
+								<div class="clearfix">
+									<label for="contentNum"><bean:message
+											key="labels.index_num" /></label>
+									<div class="input">
+										<html:select property="num" styleId="numSearchOption"
+											styleClass="span4" style="display:block;">
+											<option value="">
+												<bean:message key="labels.search_result_select_num" />
+											</option>
+											<html:option value="10">10</html:option>
+											<html:option value="20">20</html:option>
+											<html:option value="30">30</html:option>
+											<html:option value="40">40</html:option>
+											<html:option value="50">50</html:option>
+											<html:option value="100">100</html:option>
+										</html:select>
 									</div>
-								</c:if>
+								</div>
 								<div class="clearfix">
 									<label for="contentSort"><bean:message
 											key="labels.index_sort" /></label>
@@ -160,23 +157,37 @@
 									</div>
 								</div>
 								<div class="clearfix">
-									<label for="contentNum"><bean:message
-											key="labels.index_num" /></label>
+									<label for="contentLang"><bean:message
+											key="labels.index_lang" /></label>
 									<div class="input">
-										<html:select property="num" styleId="numSearchOption"
-											styleClass="span4" style="display:block;">
-											<option value="">
-												<bean:message key="labels.search_result_select_num" />
-											</option>
-											<html:option value="10">10</html:option>
-											<html:option value="20">20</html:option>
-											<html:option value="30">30</html:option>
-											<html:option value="40">40</html:option>
-											<html:option value="50">50</html:option>
-											<html:option value="100">100</html:option>
+										<html:select property="lang"
+											styleId="langSearchOption" multiple="true"
+											styleClass="span4">
+											<c:forEach var="item" items="${langItems}">
+												<html:option value="${f:u(item.value)}">
+																	${f:h(item.label)}
+																</html:option>
+											</c:forEach>
 										</html:select>
 									</div>
 								</div>
+								<c:if test="${displayLabelTypeItems}">
+									<div class="clearfix">
+										<label for="contentLabelType"><bean:message
+												key="labels.index_label" /></label>
+										<div class="input">
+											<html:select property="fields.label"
+												styleId="labelTypeSearchOption" multiple="true"
+												styleClass="span4">
+												<c:forEach var="item" items="${labelTypeItems}">
+													<html:option value="${f:u(item.value)}">
+														${f:h(item.label)}
+													</html:option>
+												</c:forEach>
+											</html:select>
+										</div>
+									</div>
+								</c:if>
 							</fieldset>
 						</div>
 						<div class="modal-footer">
-- 
GitLab