fix #128, remove mobile jsp and minor fixes.

This commit is contained in:
Shinsuke Sugaya 2014-03-09 15:54:40 +09:00
parent b93e053482
commit ef4e3b4fe7
22 changed files with 218 additions and 143 deletions

View file

@ -205,6 +205,8 @@ public class IndexAction {
public String username;
public String appendHighlightQueries;
public String getPagingQuery() {
if (pagingQuery == null) {
final StringBuilder buf = new StringBuilder();
@ -317,7 +319,7 @@ public class IndexAction {
return "error.jsp";
}
final String content = viewHelper.createCacheContent(doc);
final String content = viewHelper.createCacheContent(doc, indexForm.hq);
if (content == null) {
errorMessage = MessageResourcesUtil.getMessage(RequestUtil
.getRequest().getLocale(), "errors.docid_not_found",
@ -1002,6 +1004,16 @@ public class IndexAction {
searchLogHelper.addSearchLog(searchLog);
}
final String[] highlightQueries = (String[]) request
.getAttribute(Constants.HIGHLIGHT_QUERIES);
if (highlightQueries != null) {
final StringBuilder buf = new StringBuilder(100);
for (final String q : highlightQueries) {
buf.append("&hq=").append(q);
}
appendHighlightQueries = buf.toString();
}
Beans.copy(documentItems, this)
.includes("pageSize", "currentPageNumber", "allRecordCount",
"allPageCount", "existNextPage", "existPrevPage",
@ -1182,6 +1194,7 @@ public class IndexAction {
username = loginInfo.getUsername();
}
}
}
protected void buildInitParams() {

View file

@ -65,6 +65,8 @@ public class IndexForm implements Serializable {
@Maxbytelength(maxbytelength = 100)
public String docId;
public String[] hq;
// xml/json
@Maxbytelength(maxbytelength = 20)

View file

@ -30,14 +30,19 @@ import jp.sf.fess.db.exentity.PathMapping;
import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.annotation.tiger.InitMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PathMappingHelper implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory
.getLogger(PathMappingHelper.class);
private final Map<String, List<PathMapping>> pathMappingMap = new HashMap<String, List<PathMapping>>();
private List<PathMapping> cachedPathMappingList = null;
private volatile List<PathMapping> cachedPathMappingList = null;
@InitMethod
public void init() {
@ -45,14 +50,19 @@ public class PathMappingHelper implements Serializable {
ptList.add(CDef.ProcessType.Displaying);
ptList.add(CDef.ProcessType.Both);
final PathMappingCB cb = new PathMappingCB();
try {
final PathMappingBhv pathMappingBhv = SingletonS2Container
.getComponent(PathMappingBhv.class);
final PathMappingCB cb = new PathMappingCB();
cb.query().setDeletedBy_IsNull();
cb.query().addOrderBy_SortOrder_Asc();
cb.query().setProcessType_InScope_AsProcessType(ptList);
cb.query().setDeletedBy_IsNull();
cb.query().addOrderBy_SortOrder_Asc();
cb.query().setProcessType_InScope_AsProcessType(ptList);
cachedPathMappingList = SingletonS2Container.getComponent(
PathMappingBhv.class).selectList(cb);
cachedPathMappingList = pathMappingBhv.selectList(cb);
} catch (final Exception e) {
logger.warn("Failed to load path mappings.", e);
}
}
public void setPathMappingList(final String sessionId,
@ -86,6 +96,13 @@ public class PathMappingHelper implements Serializable {
}
public String replaceUrl(final String url) {
if (cachedPathMappingList == null) {
synchronized (this) {
if (cachedPathMappingList == null) {
init();
}
}
}
return replaceUrl(cachedPathMappingList, url);
}

View file

@ -96,6 +96,8 @@ public class QueryHelper implements Serializable {
protected Set<String> apiResponseFieldSet;
protected Set<String> highlightFieldSet = new HashSet<>();
protected String[] responseFields = new String[] { "id", "docId", "score",
"boost", "contentLength", "host", "site", "lastModified",
"mimetype", "filetype_s", "created", TITLE_FIELD, "digest", "url",
@ -376,7 +378,7 @@ public class QueryHelper implements Serializable {
}
nonPrefix = true;
operator = _AND_;
if (!LABEL_FIELD.equals(field)) {
if (highlightFieldSet.contains(field)) {
highLightQueryList.add(targetWord);
}
if (fieldLogMap != null) {
@ -1187,6 +1189,10 @@ public class QueryHelper implements Serializable {
this.supportedSortFields = supportedSortFields;
}
public void addHighlightField(final String field) {
highlightFieldSet.add(field);
}
/**
* @return the highlightSnippetSize
*/

View file

@ -28,6 +28,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
@ -374,7 +375,8 @@ public class ViewHelper implements Serializable {
return file.isFile();
}
public String createCacheContent(final Map<String, Object> doc) {
public String createCacheContent(final Map<String, Object> doc,
final String[] queries) {
final FileTemplateLoader loader = new FileTemplateLoader(new File(
ResourceUtil.getViewTemplatePath(StringUtil.EMPTY)));
@ -401,6 +403,20 @@ public class ViewHelper implements Serializable {
doc.put("cacheMsg", MessageResourcesUtil.getMessage(locale,
"labels.search_cache_msg", url, created));
doc.put("queries", queries);
final String cache = (String) doc.get("cache");
if (cache != null) {
if (queries != null && queries.length > 0) {
doc.put("hlCache", replaceHighlightQueries(cache, queries));
} else {
doc.put("hlCache", cache);
}
} else {
doc.put("cache", StringUtil.EMPTY);
doc.put("hlCache", StringUtil.EMPTY);
}
try {
final Template template = handlebars.compile(cacheTemplateName);
final Context hbsContext = Context.newContext(doc);
@ -412,6 +428,42 @@ public class ViewHelper implements Serializable {
return null;
}
protected String replaceHighlightQueries(final String cache,
final String[] queries) {
final StringBuffer buf = new StringBuffer(cache.length() + 100);
final StringBuffer segBuf = new StringBuffer(1000);
final Pattern p = Pattern.compile("<[^>]+>");
final Matcher m = p.matcher(cache);
final String[] regexQueries = new String[queries.length];
final String[] hlQueries = new String[queries.length];
for (int i = 0; i < queries.length; i++) {
regexQueries[i] = Pattern.quote(queries[i]);
hlQueries[i] = highlightTagPre + queries[i] + highlightTagPost;
}
while (m.find()) {
segBuf.setLength(0);
m.appendReplacement(segBuf, StringUtil.EMPTY);
String segment = segBuf.toString();
for (int i = 0; i < queries.length; i++) {
segment = Pattern
.compile(regexQueries[i], Pattern.CASE_INSENSITIVE)
.matcher(segment).replaceAll(hlQueries[i]);
}
buf.append(segment);
buf.append(m.group(0));
}
segBuf.setLength(0);
m.appendTail(segBuf);
String segment = segBuf.toString();
for (int i = 0; i < queries.length; i++) {
segment = Pattern
.compile(regexQueries[i], Pattern.CASE_INSENSITIVE)
.matcher(segment).replaceAll(hlQueries[i]);
}
buf.append(segment);
return buf.toString();
}
public boolean isUseSession() {
return useSession;
}

View file

@ -118,7 +118,9 @@ public abstract class AbstractFessXpathTransformer extends XpathTransformer {
protected void putResultDataBody(final Map<String, Object> dataMap,
final String key, final Object value) {
if (dataMap.containsKey(key)) {
if ("url".equals(key)) {
dataMap.put(key, value);
} else if (dataMap.containsKey(key)) {
if (appendResultData) {
final Object oldValue = dataMap.get(key);
if (key.endsWith("_m")) {

View file

@ -68,6 +68,12 @@
"contentLength", "host", "site", "lastModified", "mimetype", "filetype_s",
"created", "title", "digest", "url"}</arg>
</initMethod>
<initMethod name="addHighlightField">
<arg>"title"</arg>
</initMethod>
<initMethod name="addHighlightField">
<arg>"content"</arg>
</initMethod>
<!--
<property name="additionalGeoQuery">"location_i_i:1"</property>
<property name="responseFields">new String[]{ "id", "docId", "score",

View file

@ -72,10 +72,6 @@ new String[] {
"-XX:G1ReservePercent=10",
-->
</property>
<!--
"-XX:+OptimizeStringConcat",
"-XX:+UseCompressedStrings",
-->
<!-- remote debug
"-Xdebug",
"-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=127.0.0.1:8000",

View file

@ -4,4 +4,4 @@
<div style="border:1px solid #999;margin:5px -1px;padding:0;">
<div style="color:#000;background:#ddd;border:1px solid #666;margin:10px 15px;padding:5px;text-align:left;">{{cacheMsg}}</div>
</div>
{{{cache}}}
{{{hlCache}}}

View file

@ -1,9 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<html>
<head>
<jsp:include page="indexHtmlHead.jsp"/>
</head>
<body>
<jsp:include page="indexMain.jsp"/>
</body>
</html>

View file

@ -1,4 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<meta http-equiv="Content-Type" content="text/html; charset=<m:charset/>" />
<meta content="no-cache" http-equiv="Cache-Control"/>
<title><bean:message key="labels.mobile_search_title"/></title>

View file

@ -1,14 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<div>
<div style="text-align: center;">
<m:img src="logo-top.gif" magniWidth="0.8" style="vertical-align: middle;" />
<br/>
<s:form>
<div>
<html:text property="query" title="Search" size="20" maxlength="1000" />
<br/>
<input type="submit" value="<bean:message key="labels.top.search"/>" name="search" />
</div>
</s:form>
</div>
</div>

View file

@ -1,18 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<html>
<head>
<jsp:include page="searchHtmlHead.jsp"/>
</head>
<body>
<jsp:include page="searchHeader.jsp"/>
<c:choose>
<c:when test="${f:h(allRecordCount) != 0}">
<jsp:include page="searchResults.jsp"/>
</c:when>
<c:otherwise>
<jsp:include page="searchNoResult.jsp"/>
</c:otherwise>
</c:choose>
<jsp:include page="searchFooter.jsp"/>
</body>
</html>

View file

@ -1,5 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<hr style="border-style: solid; border-color: #ffffff;"/>
<div style="font-size: x-small; text-align: center;">
<bean:message key="labels.footer.copyright"/>
</div>

View file

@ -1,13 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<div id="header">
<div>
<s:form>
<div>
<m:img src="logo-top.gif" magniWidth="0.3" />
<br/>
<html:text property="query" title="Search" size="16" maxlength="1000" />
<input type="submit" value="<bean:message key="labels.search"/>" name="search"/>
</div>
</s:form>
</div>
</div>

View file

@ -1,4 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<meta http-equiv="Content-Type" content="text/html; charset=<m:charset/>" />
<meta content="no-cache" http-equiv="Cache-Control"/>
<title>${f:h(query)} - <bean:message key="labels.search_title"/></title>

View file

@ -1,4 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<div id="result">
<bean:message key="labels.did_not_match" arg0="${f:h(query)}"/>
</div>

View file

@ -1,55 +0,0 @@
<%@page pageEncoding="UTF-8" %>
<div id="result">
<div>
<c:forEach var="doc" varStatus="s" items="${documentItems}">
<div>
<a href="${doc.urlLink}"><span>${f:h(doc.contentTitle)}</span></a>
<span id="snip">
<br/>
<span style="color: #666666;">
${doc.contentDescription}
</span>
</span>
<span style="color: #008000;">
<br/>
${f:h(doc.site)}
</span>
<br/>
</div>
<br/>
</c:forEach>
</div>
</div>
<div id="subfooter" style="text-align: center;">
<p>
<c:if test="${existPrevPage}">
<span>
<s:link href="prev?query=${f:u(query)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}">
<bean:message key="labels.prev_page"/>
</s:link>
</span>
</c:if>
<c:forEach var="pageNumber" varStatus="s" items="${pageNumberList}">
<c:if test="${pageNumber == currentPageNumber}">
<span>
${pageNumber}
</span>
</c:if>
<c:if test="${pageNumber != currentPageNumber}">
<span>
<s:link href="move?query=${f:u(query)}&pn=${f:u(pageNumber)}&num=${f:u(pageSize)}">
${f:h(pageNumber)}
</s:link>
</span>
</c:if>
</c:forEach>
<c:if test="${existNextPage}">
<span>
<s:link href="next?query=${f:u(query)}&pn=${f:u(currentPageNumber)}&num=${f:u(pageSize)}">
<bean:message key="labels.next_page"/>
</s:link>
</span>
</c:if>
</p>
</div>

View file

@ -36,7 +36,7 @@
<div class="site ellipsis">
<cite>${f:h(doc.site)}</cite>
<c:if test="${doc.hasCache_s_s=='true'}">
<a href="cache?docId=${doc.docId}" class="cache"><bean:message
<a href="cache?docId=${doc.docId}${appendHighlightQueries}" class="cache"><bean:message
key="labels.search_result_cache" /></a>
</c:if>
</div>

View file

@ -57,6 +57,7 @@ h3 {
#result .body a.cache {
color: #093;
margin-left: 10px;
}
#result .favorited {

View file

@ -0,0 +1,88 @@
/*
* Copyright 2009-2014 the 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 jp.sf.fess.helper;
import org.seasar.extension.unit.S2TestCase;
public class ViewHelperTest extends S2TestCase {
public ViewHelper viewHelper;
@Override
protected String getRootDicon() throws Throwable {
return "jp/sf/fess/helper/view.dicon";
}
public void test_replaceHighlightQueries() {
String text;
String[] queries;
text = "<a>123<b>456<c>";
queries = new String[] { "123", "456" };
assertEquals("<a><em>123</em><b><em>456</em><c>",
viewHelper.replaceHighlightQueries(text, queries));
text = "<123><456>";
queries = new String[] { "123", "456" };
assertEquals("<123><456>",
viewHelper.replaceHighlightQueries(text, queries));
text = "123<aaa 123>456<bbb 456>123";
queries = new String[] { "123", "456" };
assertEquals("<em>123</em><aaa 123><em>456</em><bbb 456><em>123</em>",
viewHelper.replaceHighlightQueries(text, queries));
text = "abc";
queries = new String[] { "123" };
assertEquals("abc", viewHelper.replaceHighlightQueries(text, queries));
text = "123";
queries = new String[] { "123" };
assertEquals("<em>123</em>",
viewHelper.replaceHighlightQueries(text, queries));
text = "abc123efg";
queries = new String[] { "123" };
assertEquals("abc<em>123</em>efg",
viewHelper.replaceHighlightQueries(text, queries));
text = "123";
queries = new String[] { "123", "456" };
assertEquals("<em>123</em>",
viewHelper.replaceHighlightQueries(text, queries));
text = "123456";
queries = new String[] { "123", "456" };
assertEquals("<em>123</em><em>456</em>",
viewHelper.replaceHighlightQueries(text, queries));
text = "a123b456c";
queries = new String[] { "123", "456" };
assertEquals("a<em>123</em>b<em>456</em>c",
viewHelper.replaceHighlightQueries(text, queries));
text = "abc";
queries = new String[] { "abc" };
assertEquals("<em>abc</em>",
viewHelper.replaceHighlightQueries(text, queries));
text = "1ABC2";
queries = new String[] { "abc" };
assertEquals("1<em>abc</em>2",
viewHelper.replaceHighlightQueries(text, queries));
}
}

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<component name="viewHelper" class="jp.sf.fess.helper.ViewHelper">
</component>
<component name="pathMappingHelper" class="jp.sf.fess.helper.PathMappingHelper">
</component>
<component name="userAgentHelper" class="jp.sf.fess.helper.UserAgentHelper">
</component>
<component name="crawlerProperties" class="org.codelibs.core.util.DynamicProperties">
<arg>
@org.seasar.framework.util.ResourceUtil@getBuildDir(@jp.sf.fess.FessClass@class).getCanonicalPath()
+ "/conf/crawler.properties"
</arg>
</component>
</components>