diff --git a/src/main/java/org/codelibs/fess/api/gsa/GsaApiManager.java b/src/main/java/org/codelibs/fess/api/gsa/GsaApiManager.java
index 5f0846026..028e6ac6e 100644
--- a/src/main/java/org/codelibs/fess/api/gsa/GsaApiManager.java
+++ b/src/main/java/org/codelibs/fess/api/gsa/GsaApiManager.java
@@ -16,6 +16,7 @@
package org.codelibs.fess.api.gsa;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
@@ -60,6 +61,9 @@ import org.slf4j.LoggerFactory;
public class GsaApiManager extends BaseApiManager implements WebApiManager {
private static final Logger logger = LoggerFactory.getLogger(GsaApiManager.class);
+ private static final String OUTPUT_XML = "xml"; // or xml_no_dtd
+ // http://www.google.com/google.dtd.
+
private static final String GSA_META_SUFFIX = "_s";
protected String gsaPathPrefix = "/gsa";
@@ -94,12 +98,28 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
}
}
+ protected void appendParam(final StringBuilder buf, final String name, final String value) throws UnsupportedEncodingException {
+ appendParam(buf, name, value, URLEncoder.encode(value, Constants.UTF_8));
+ }
+
+ protected void appendParam(final StringBuilder buf, final String name, final String value, final String original)
+ throws UnsupportedEncodingException {
+ buf.append("");
+ }
+
protected void processSearchRequest(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) {
final SearchService searchService = ComponentUtil.getComponent(SearchService.class);
final FessConfig fessConfig = ComponentUtil.getFessConfig();
+ final boolean xmlDtd = OUTPUT_XML.equals(request.getParameter("output"));
if (!fessConfig.isAcceptedSearchReferer(request.getHeader("referer"))) {
- writeXmlResponse(99, false, StringUtil.EMPTY, "Referer is invalid.");
+ writeXmlResponse(99, xmlDtd, StringUtil.EMPTY, "Referer is invalid.");
return;
}
@@ -108,7 +128,6 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
String query = null;
final StringBuilder buf = new StringBuilder(1000);
request.setAttribute(Constants.SEARCH_LOG_ACCESS_TYPE, Constants.SEARCH_LOG_ACCESS_TYPE_GSA);
- boolean xmlDtd = false;
try {
final SearchRenderData data = new SearchRenderData();
final GsaRequestParams params = new GsaRequestParams(request, fessConfig);
@@ -124,10 +143,6 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
if (StringUtil.isNotBlank(getFieldsParam)) {
getFields.addAll(Arrays.asList(getFieldsParam.split("\\.")));
}
- // DTD
- if ("xml".equals(request.getParameter("output"))) {
- xmlDtd = true;
- }
final StringBuilder requestUri = new StringBuilder(request.getRequestURI());
if (request.getQueryString() != null) {
requestUri.append("?").append(request.getQueryString());
@@ -138,88 +153,92 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
final String oe = "UTF-8";
// IP address
final String ip = ComponentUtil.getViewHelper().getClientIp(request);
- final String start = request.getParameter("start");
- long startNumber = 1;
- if (StringUtil.isNotBlank(start)) {
- startNumber = Long.parseLong(start) + 1;
- }
- long endNumber = startNumber + data.getPageSize() - 1;
- if (endNumber > allRecordCount) {
- endNumber = allRecordCount;
- }
- buf.append("");
- buf.append(escapeXml(query));
- buf.append("
");
buf.append("");
buf.append(execTime);
buf.append("");
+ buf.append("");
+ buf.append(escapeXml(query));
+ buf.append("
");
for (final Entry entry : request.getParameterMap().entrySet()) {
final String[] values = entry.getValue();
if (values == null) {
continue;
}
final String key = entry.getKey();
+ if ("sort".equals(key)) {
+ continue;
+ }
for (final String value : values) {
- buf.append("");
+ appendParam(buf, key, value);
}
}
- buf.append("");
- buf.append("");
- buf.append("");
+ appendParam(buf, "ie", ie);
+ if (request.getParameter("oe") == null) {
+ appendParam(buf, "oe", oe);
+ }
+ final String[] langs = params.getLanguages();
+ if (langs.length > 0) {
+ appendParam(buf, "inlang", langs[0]);
+ appendParam(buf, "ulang", langs[0]);
+ }
+ appendParam(buf, "ip", ip);
+ appendParam(buf, "access", "p");
+ appendParam(buf, "sort", params.getSortParam(), params.getSortParam());
+ appendParam(buf, "entqr", "3");
+ appendParam(buf, "entqrm", "0");
+ appendParam(buf, "wc", "200");
+ appendParam(buf, "wc_mc", "1");
if (!documentItems.isEmpty()) {
buf.append("");
buf.append("");
buf.append(allRecordCount);
buf.append("");
- if (endNumber < allRecordCount) {
+ if (data.isExistPrevPage() || data.isExistNextPage()) {
buf.append("");
- buf.append("");
- buf.append(escapeXml(uriQueryString.replaceFirst("start=([^&]+)", "start=" + endNumber)));
- buf.append("");
+ if (data.isExistPrevPage()) {
+ long s = data.getCurrentStartRecordNumber() - data.getPageSize() - 1;
+ if (s < 0) {
+ s = 0;
+ }
+ buf.append("");
+ buf.append(escapeXml(uriQueryString.replaceFirst("start=([0-9]+)", "start=" + s)));
+ buf.append("");
+ }
+ if (data.isExistNextPage()) {
+ buf.append("");
+ buf.append(escapeXml(uriQueryString.replaceFirst("start=([0-9]+)", "start=" + data.getCurrentEndRecordNumber())));
+ buf.append("");
+ }
buf.append("");
}
- long recordNumber = startNumber;
+ long recordNumber = data.getCurrentStartRecordNumber();
for (final Map document : documentItems) {
buf.append("");
final String url = DocumentUtil.getValue(document, fessConfig.getIndexFieldUrl(), String.class);
- document.remove(fessConfig.getIndexFieldUrl());
document.put("UE", url);
document.put("U", URLDecoder.decode(url, Constants.UTF_8));
- document.put("T", DocumentUtil.getValue(document, fessConfig.getIndexFieldTitle(), String.class));
- document.remove(fessConfig.getIndexFieldTitle());
- final float score = DocumentUtil.getValue(document, fessConfig.getIndexFieldBoost(), Float.class, Float.valueOf(0));
- document.remove(fessConfig.getIndexFieldBoost());
- document.put("RK", (int) (score * 10));
- document.put("S",
- DocumentUtil
- .getValue(document, fessConfig.getResponseFieldContentDescription(), String.class, StringUtil.EMPTY)
- .replaceAll("<(/*)em>", "<$1b>"));
- document.remove(fessConfig.getResponseFieldContentDescription());
+ document.put("T", DocumentUtil.getValue(document, fessConfig.getResponseFieldContentTitle(), String.class));
+ final float score = DocumentUtil.getValue(document, Constants.SCORE, Float.class, Float.NaN);
+ int rk = 10;
+ if (!Float.isNaN(score)) {
+ if (score < 0.0) {
+ rk = 0;
+ } else if (score > 1.0) {
+ rk = 10;
+ } else {
+ rk = (int) (score * 10.0);
+ }
+ }
+ document.put("RK", rk);
+ document.put("S", DocumentUtil.getValue(document, fessConfig.getResponseFieldContentDescription(), String.class,
+ StringUtil.EMPTY));
final String lang = DocumentUtil.getValue(document, fessConfig.getIndexFieldLang(), String.class);
if (StringUtil.isNotBlank(lang)) {
document.put("LANG", lang);
@@ -251,6 +270,14 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
}
}
}
+ buf.append("").append(escapeXml("FESS")).append("");
+ String lastModified = DocumentUtil.getValue(document, fessConfig.getIndexFieldLastModified(), String.class);
+ if (StringUtil.isBlank(lastModified)) {
+ lastModified = StringUtil.EMPTY;
+ }
+ lastModified = lastModified.split("T")[0];
+ buf.append("");
+
buf.append("");
buf.append("");
buf.append(" 0) {
+ return langs;
+ }
+ if (request.getHeader("Accept-Language") != null) {
+ return Collections.list(request.getLocales()).stream().map(l -> l.getLanguage()).toArray(n -> new String[n]);
+ }
+ return new String[] { fessConfig.getQueryGsaDefaultLang() };
}
@Override
@@ -463,9 +506,50 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
return createFacetInfo(request);
}
+ public String getSortParam() {
+ return sortParam;
+ }
+
@Override
public String getSort() {
- return request.getParameter("sort");
+ // Sort By Relevance (Default)
+ // Sort By Date: date:::
+ // Sort by Metadata: meta::::::
+ if (StringUtil.isBlank(sortParam)) {
+ return null;
+ }
+
+ final String[] values = sortParam.split(":");
+ if (values.length > 0) {
+ if ("date".equals(values[0])) {
+ final StringBuilder buf = new StringBuilder();
+ buf.append(fessConfig.getIndexFieldTimestamp());
+ if (values.length > 1) {
+ if ("A".equals(values[1])) {
+ buf.append(".asc");
+ } else if ("D".equals(values[1])) {
+ buf.append(".desc");
+ }
+ }
+ buf.append(",score.desc");
+ return buf.toString();
+ } else if ("meta".equals(values[0]) && values.length > 1) {
+ final StringBuilder buf = new StringBuilder();
+ buf.append(values[1]);
+ if (values.length > 2) {
+ if ("A".equals(values[2])) {
+ buf.append(".asc");
+ } else if ("D".equals(values[2])) {
+ buf.append(".desc");
+ }
+ }
+ buf.append(",score.desc");
+ return buf.toString();
+ }
+ }
+
+ sortParam = "";
+ return null;
}
@Override
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/backup/AdminBackupAction.java b/src/main/java/org/codelibs/fess/app/web/admin/backup/AdminBackupAction.java
index cac38e368..9ecc61170 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/backup/AdminBackupAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/backup/AdminBackupAction.java
@@ -44,12 +44,16 @@ import org.codelibs.core.misc.Pair;
import org.codelibs.elasticsearch.runner.net.CurlResponse;
import org.codelibs.fess.Constants;
import org.codelibs.fess.app.web.base.FessAdminAction;
+import org.codelibs.fess.es.config.exbhv.FileConfigBhv;
+import org.codelibs.fess.es.config.exbhv.LabelTypeBhv;
+import org.codelibs.fess.es.config.exbhv.WebConfigBhv;
import org.codelibs.fess.es.log.exbhv.ClickLogBhv;
import org.codelibs.fess.es.log.exbhv.FavoriteLogBhv;
import org.codelibs.fess.es.log.exbhv.SearchLogBhv;
import org.codelibs.fess.es.log.exbhv.UserInfoBhv;
import org.codelibs.fess.mylasta.direction.FessConfig;
import org.codelibs.fess.util.ComponentUtil;
+import org.codelibs.fess.util.GsaConfigParser;
import org.codelibs.fess.util.RenderDataUtil;
import org.lastaflute.core.magic.async.AsyncManager;
import org.lastaflute.web.Execute;
@@ -59,6 +63,7 @@ import org.lastaflute.web.response.StreamResponse;
import org.lastaflute.web.ruts.process.ActionRuntime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
/**
* @author shinsuke
@@ -74,6 +79,15 @@ public class AdminBackupAction extends FessAdminAction {
@Resource
private AsyncManager asyncManager;
+ @Resource
+ private WebConfigBhv webConfigBhv;
+
+ @Resource
+ private FileConfigBhv fileConfigBhv;
+
+ @Resource
+ private LabelTypeBhv labelTypeBhv;
+
@Override
protected void setupHtmlData(final ActionRuntime runtime) {
super.setupHtmlData(runtime);
@@ -98,6 +112,16 @@ public class AdminBackupAction extends FessAdminAction {
} catch (final IOException e) {
logger.warn("Failed to process system.properties file: " + form.bulkFile.getFileName(), e);
}
+ } else if (fileName.startsWith("gsa") && fileName.endsWith(".xml")) {
+ GsaConfigParser configParser = ComponentUtil.getComponent(GsaConfigParser.class);
+ try (final InputStream in = form.bulkFile.getInputStream()) {
+ configParser.parse(new InputSource(in));
+ } catch (final IOException e) {
+ logger.warn("Failed to process gsa.xml file: " + form.bulkFile.getFileName(), e);
+ }
+ configParser.getWebConfig().ifPresent(c -> webConfigBhv.insert(c));
+ configParser.getFileConfig().ifPresent(c -> fileConfigBhv.insert(c));
+ labelTypeBhv.batchInsert(Arrays.stream(configParser.getLabelTypes()).collect(Collectors.toList()));
} else {
try (CurlResponse response = ComponentUtil.getCurlHelper().post("/_bulk").onConnect((req, con) -> {
con.setDoOutput(true);
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/group/AdminGroupAction.java b/src/main/java/org/codelibs/fess/app/web/admin/group/AdminGroupAction.java
index 12c6d2edc..483fee3f3 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/group/AdminGroupAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/group/AdminGroupAction.java
@@ -255,6 +255,7 @@ public class AdminGroupAction extends FessAdminAction {
public static OptionalEntity getGroup(final CreateForm form) {
return getEntity(form).map(entity -> {
+ copyMapToBean(form.attributes, entity, op -> op.exclude(Constants.COMMON_CONVERSION_RULE));
copyBeanToBean(form, entity, op -> op.exclude(Constants.COMMON_CONVERSION_RULE));
return entity;
});
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/role/AdminRoleAction.java b/src/main/java/org/codelibs/fess/app/web/admin/role/AdminRoleAction.java
index 38b378f53..07050d3c0 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/role/AdminRoleAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/role/AdminRoleAction.java
@@ -209,6 +209,7 @@ public class AdminRoleAction extends FessAdminAction {
public static OptionalEntity getRole(final CreateForm form) {
return getEntity(form).map(entity -> {
+ copyMapToBean(form.attributes, entity, op -> op.exclude(Constants.COMMON_CONVERSION_RULE));
copyBeanToBean(form, entity, op -> op.exclude(Constants.COMMON_CONVERSION_RULE));
return entity;
});
diff --git a/src/main/java/org/codelibs/fess/app/web/admin/systeminfo/AdminSysteminfoAction.java b/src/main/java/org/codelibs/fess/app/web/admin/systeminfo/AdminSysteminfoAction.java
index 17d995be2..0356bc718 100644
--- a/src/main/java/org/codelibs/fess/app/web/admin/systeminfo/AdminSysteminfoAction.java
+++ b/src/main/java/org/codelibs/fess/app/web/admin/systeminfo/AdminSysteminfoAction.java
@@ -26,8 +26,10 @@ import org.codelibs.core.lang.StringUtil;
import org.codelibs.core.misc.DynamicProperties;
import org.codelibs.fess.Constants;
import org.codelibs.fess.app.web.base.FessAdminAction;
+import org.codelibs.fess.mylasta.direction.FessConfig;
import org.codelibs.fess.util.ComponentUtil;
import org.codelibs.fess.util.RenderDataUtil;
+import org.lastaflute.core.direction.ObjectiveConfig;
import org.lastaflute.web.Execute;
import org.lastaflute.web.response.HtmlResponse;
import org.lastaflute.web.response.render.RenderData;
@@ -38,6 +40,8 @@ import org.lastaflute.web.ruts.process.ActionRuntime;
*/
public class AdminSysteminfoAction extends FessAdminAction {
+ private static final String MASKED_VALUE = "XXXXXXXX";
+
// ===================================================================================
// Attribute
// =========
@@ -83,7 +87,7 @@ public class AdminSysteminfoAction extends FessAdminAction {
}
protected void registerFessPropItems(final RenderData data) {
- RenderDataUtil.register(data, "fessPropItems", getFessPropItems());
+ RenderDataUtil.register(data, "fessPropItems", getFessPropItems(fessConfig));
}
protected void registerBugReportItems(final RenderData data) {
@@ -106,15 +110,42 @@ public class AdminSysteminfoAction extends FessAdminAction {
return itemList;
}
- public static List