Browse Source

fix #35 and fix #36

Shinsuke Sugaya 11 years ago
parent
commit
568f345a5a
27 changed files with 292 additions and 192 deletions
  1. 3 1
      src/main/java/jp/sf/fess/Constants.java
  2. 97 58
      src/main/java/jp/sf/fess/action/IndexAction.java
  3. 1 1
      src/main/java/jp/sf/fess/action/MobileAction.java
  4. 1 1
      src/main/java/jp/sf/fess/action/admin/SearchListAction.java
  5. 2 2
      src/main/java/jp/sf/fess/ds/impl/AbstractDataStoreImpl.java
  6. 39 22
      src/main/java/jp/sf/fess/ds/impl/IndexUpdateCallbackImpl.java
  7. 2 2
      src/main/java/jp/sf/fess/form/IndexForm.java
  8. 11 0
      src/main/java/jp/sf/fess/helper/SystemHelper.java
  9. 1 1
      src/main/java/jp/sf/fess/helper/UserInfoHelper.java
  10. 24 24
      src/main/java/jp/sf/fess/helper/impl/CookieUserInfoHelperImpl.java
  11. 7 7
      src/main/java/jp/sf/fess/helper/impl/QueryHelperImpl.java
  12. 2 1
      src/main/java/jp/sf/fess/job/TriggeredJob.java
  13. 10 11
      src/main/java/jp/sf/fess/service/FavoriteLogService.java
  14. 30 3
      src/main/java/jp/sf/fess/service/SearchService.java
  15. 4 0
      src/main/java/jp/sf/fess/solr/IndexUpdater.java
  16. 2 2
      src/main/java/jp/sf/fess/transformer/AbstractFessFileTransformer.java
  17. 2 4
      src/main/java/jp/sf/fess/transformer/FessXpathTransformer.java
  18. 4 4
      src/main/resources/app.dicon
  19. 5 3
      src/main/resources/application.properties
  20. 5 3
      src/main/resources/application_ja.properties
  21. 1 1
      src/main/webapp/WEB-INF/view/common/help.jsp
  22. 1 1
      src/main/webapp/WEB-INF/view/common/help_ja.jsp
  23. 4 4
      src/main/webapp/WEB-INF/view/error/header.jsp
  24. 4 4
      src/main/webapp/WEB-INF/view/header.jsp
  25. 4 4
      src/main/webapp/WEB-INF/view/index.jsp
  26. 7 8
      src/main/webapp/WEB-INF/view/searchResults.jsp
  27. 19 20
      src/main/webapp/js/search.js

+ 3 - 1
src/main/java/jp/sf/fess/Constants.java

@@ -271,7 +271,7 @@ public class Constants extends CoreLibConstants {
 
 
     public static final String STATS_REPORT_TYPE = "reportType";
     public static final String STATS_REPORT_TYPE = "reportType";
 
 
-    public static final String RESULT_URL_CACHE = "resultUrls";
+    public static final String RESULT_DOC_ID_CACHE = "resultDocIds";
 
 
     public static final String SCREEN_SHOT_PATH_CACHE = "screenShotPaths";
     public static final String SCREEN_SHOT_PATH_CACHE = "screenShotPaths";
 
 
@@ -322,4 +322,6 @@ public class Constants extends CoreLibConstants {
 
 
     public static final String WEB_CONFIG_ID_PREFIX = "W";
     public static final String WEB_CONFIG_ID_PREFIX = "W";
 
 
+    public static final String DOC_ID = "docId";
+
 }
 }

+ 97 - 58
src/main/java/jp/sf/fess/action/IndexAction.java

@@ -81,7 +81,6 @@ import org.seasar.framework.beans.util.Beans;
 import org.seasar.framework.container.SingletonS2Container;
 import org.seasar.framework.container.SingletonS2Container;
 import org.seasar.framework.container.annotation.tiger.Binding;
 import org.seasar.framework.container.annotation.tiger.Binding;
 import org.seasar.framework.container.annotation.tiger.BindingType;
 import org.seasar.framework.container.annotation.tiger.BindingType;
-import org.seasar.framework.exception.IORuntimeException;
 import org.seasar.framework.util.InputStreamUtil;
 import org.seasar.framework.util.InputStreamUtil;
 import org.seasar.framework.util.OutputStreamUtil;
 import org.seasar.framework.util.OutputStreamUtil;
 import org.seasar.framework.util.StringUtil;
 import org.seasar.framework.util.StringUtil;
@@ -279,6 +278,27 @@ public class IndexAction {
 
 
     @Execute(validator = true, input = "index")
     @Execute(validator = true, input = "index")
     public String go() throws IOException {
     public String go() throws IOException {
+        Map<String, Object> doc = null;
+        try {
+            doc = searchService.getDocument("docId:" + indexForm.docId);
+        } catch (final Exception e) {
+            logger.warn("Failed to request: " + indexForm.docId, e);
+        }
+        if (doc == null) {
+            errorMessage = MessageResourcesUtil.getMessage(RequestUtil
+                    .getRequest().getLocale(), "errors.docid_not_found",
+                    indexForm.docId);
+            return "error.jsp";
+        }
+        final Object urlObj = doc.get("url");
+        if (urlObj == null) {
+            errorMessage = MessageResourcesUtil.getMessage(RequestUtil
+                    .getRequest().getLocale(), "errors.document_not_found",
+                    indexForm.docId);
+            return "error.jsp";
+        }
+        final String url = urlObj.toString();
+
         if (Constants.TRUE.equals(crawlerProperties.getProperty(
         if (Constants.TRUE.equals(crawlerProperties.getProperty(
                 Constants.SEARCH_LOG_PROPERTY, Constants.TRUE))) {
                 Constants.SEARCH_LOG_PROPERTY, Constants.TRUE))) {
             final String userSessionId = userInfoHelper.getUserCode();
             final String userSessionId = userInfoHelper.getUserCode();
@@ -286,7 +306,7 @@ public class IndexAction {
                 final SearchLogHelper searchLogHelper = SingletonS2Container
                 final SearchLogHelper searchLogHelper = SingletonS2Container
                         .getComponent(SearchLogHelper.class);
                         .getComponent(SearchLogHelper.class);
                 final ClickLog clickLog = new ClickLog();
                 final ClickLog clickLog = new ClickLog();
-                clickLog.setUrl(indexForm.u);
+                clickLog.setUrl(url);
                 clickLog.setRequestedTime(new Timestamp(System
                 clickLog.setRequestedTime(new Timestamp(System
                         .currentTimeMillis()));
                         .currentTimeMillis()));
                 clickLog.setQueryRequestedTime(new Timestamp(Long
                 clickLog.setQueryRequestedTime(new Timestamp(Long
@@ -295,15 +315,15 @@ public class IndexAction {
                 searchLogHelper.addClickLog(clickLog);
                 searchLogHelper.addClickLog(clickLog);
             }
             }
         }
         }
-        if (indexForm.u.startsWith("file:")) {
+        if (url.startsWith("file:")) {
             if (Constants.TRUE.equals(crawlerProperties.getProperty(
             if (Constants.TRUE.equals(crawlerProperties.getProperty(
                     Constants.SEARCH_DESKTOP_PROPERTY, Constants.FALSE))) {
                     Constants.SEARCH_DESKTOP_PROPERTY, Constants.FALSE))) {
-                final String path = indexForm.u.replaceFirst("file:/+", "//");
+                final String path = url.replaceFirst("file:/+", "//");
                 final File file = new File(path);
                 final File file = new File(path);
                 if (!file.exists()) {
                 if (!file.exists()) {
                     errorMessage = MessageResourcesUtil.getMessage(RequestUtil
                     errorMessage = MessageResourcesUtil.getMessage(RequestUtil
                             .getRequest().getLocale(),
                             .getRequest().getLocale(),
-                            "errors.not_found_on_file_system", indexForm.u);
+                            "errors.not_found_on_file_system", url);
                     return "error.jsp";
                     return "error.jsp";
                 }
                 }
                 final Desktop desktop = Desktop.getDesktop();
                 final Desktop desktop = Desktop.getDesktop();
@@ -312,7 +332,7 @@ public class IndexAction {
                 } catch (final Exception e) {
                 } catch (final Exception e) {
                     errorMessage = MessageResourcesUtil.getMessage(RequestUtil
                     errorMessage = MessageResourcesUtil.getMessage(RequestUtil
                             .getRequest().getLocale(),
                             .getRequest().getLocale(),
-                            "errors.could_not_open_on_system", indexForm.u);
+                            "errors.could_not_open_on_system", url);
                     logger.warn("Could not open " + path, e);
                     logger.warn("Could not open " + path, e);
                     return "error.jsp";
                     return "error.jsp";
                 }
                 }
@@ -324,13 +344,12 @@ public class IndexAction {
                     Constants.SEARCH_FILE_LAUNCHER_PROPERTY, Constants.TRUE))) {
                     Constants.SEARCH_FILE_LAUNCHER_PROPERTY, Constants.TRUE))) {
                 ResponseUtil.getResponse().sendRedirect(
                 ResponseUtil.getResponse().sendRedirect(
                         RequestUtil.getRequest().getContextPath()
                         RequestUtil.getRequest().getContextPath()
-                                + "/applet/launcher?uri="
-                                + S2Functions.u(indexForm.u));
+                                + "/applet/launcher?uri=" + S2Functions.u(url));
             } else {
             } else {
-                ResponseUtil.getResponse().sendRedirect(indexForm.u);
+                ResponseUtil.getResponse().sendRedirect(url);
             }
             }
         } else {
         } else {
-            ResponseUtil.getResponse().sendRedirect(indexForm.u);
+            ResponseUtil.getResponse().sendRedirect(url);
         }
         }
         return null;
         return null;
     }
     }
@@ -413,8 +432,9 @@ public class IndexAction {
         final int pageStart = Integer.parseInt(indexForm.start);
         final int pageStart = Integer.parseInt(indexForm.start);
         final int pageNum = Integer.parseInt(indexForm.num);
         final int pageNum = Integer.parseInt(indexForm.num);
         try {
         try {
-            documentItems = searchService.selectList(query, indexForm.facet,
-                    pageStart, pageNum, indexForm.geo, indexForm.mlt);
+            documentItems = searchService.getDocumentList(query,
+                    indexForm.facet, pageStart, pageNum, indexForm.geo,
+                    indexForm.mlt);
         } catch (final SolrLibQueryException e) {
         } catch (final SolrLibQueryException e) {
             if (logger.isDebugEnabled()) {
             if (logger.isDebugEnabled()) {
                 logger.debug(e.getMessage(), e);
                 logger.debug(e.getMessage(), e);
@@ -1882,10 +1902,13 @@ public class IndexAction {
             errMsg = "Not supported.";
             errMsg = "Not supported.";
             status = 10;
             status = 10;
         } else {
         } else {
-            final String userCode = userInfoHelper.getUserCode();
-            final String favoriteUrl = indexForm.u;
-
             try {
             try {
+                final Map<String, Object> doc = indexForm.docId == null ? null
+                        : searchService.getDocument("docId:" + indexForm.docId);
+                final String userCode = userInfoHelper.getUserCode();
+                final String favoriteUrl = doc == null ? null : (String) doc
+                        .get("url");
+
                 if (StringUtil.isBlank(userCode)) {
                 if (StringUtil.isBlank(userCode)) {
                     errMsg = "No user session.";
                     errMsg = "No user session.";
                     status = 2;
                     status = 2;
@@ -1893,21 +1916,20 @@ public class IndexAction {
                     errMsg = "URL is null.";
                     errMsg = "URL is null.";
                     status = 3;
                     status = 3;
                 } else {
                 } else {
-                    final String[] urls = userInfoHelper
-                            .getResultUrls(URLDecoder.decode(indexForm.queryId,
-                                    Constants.UTF_8));
-                    if (urls != null) {
-                        String targetUrl = null;
-                        final String matchUrl = favoriteUrl.replaceFirst(":/+",
-                                ":/");
-                        for (final String url : urls) {
-                            if (url.replaceFirst(":/+", ":/").equals(matchUrl)) {
-                                targetUrl = url;
+                    final String[] docIds = userInfoHelper
+                            .getResultDocIds(URLDecoder.decode(
+                                    indexForm.queryId, Constants.UTF_8));
+                    if (docIds != null) {
+                        boolean found = false;
+                        for (final String docId : docIds) {
+                            if (indexForm.docId.equals(docId)) {
+                                found = true;
                                 break;
                                 break;
                             }
                             }
                         }
                         }
-                        if (targetUrl != null) {
-                            if (favoriteLogService.addUrl(userCode, targetUrl)) {
+                        if (found) {
+                            if (favoriteLogService
+                                    .addUrl(userCode, favoriteUrl)) {
                                 body = "\"result\":\"ok\"";
                                 body = "\"result\":\"ok\"";
                             } else {
                             } else {
                                 errMsg = "Failed to add url.";
                                 errMsg = "Failed to add url.";
@@ -1954,19 +1976,41 @@ public class IndexAction {
                     errMsg = "Query ID is null.";
                     errMsg = "Query ID is null.";
                     status = 3;
                     status = 3;
                 } else {
                 } else {
-                    String[] urls = userInfoHelper.getResultUrls(URLDecoder
-                            .decode(indexForm.queryId, Constants.UTF_8));
-                    urls = favoriteLogService.getUrls(userCode, urls);
+                    final String[] docIds = userInfoHelper
+                            .getResultDocIds(indexForm.queryId);
+                    final List<Map<String, Object>> docList = searchService
+                            .getDocumentListByDocIds(docIds, MAX_PAGE_SIZE);
+                    List<String> urlList = new ArrayList<String>(docList.size());
+                    for (final Map<String, Object> doc : docList) {
+                        final Object urlObj = doc.get("url");
+                        if (urlObj != null) {
+                            urlList.add(urlObj.toString());
+                        }
+                    }
+                    urlList = favoriteLogService.getUrlList(userCode, urlList);
+                    final List<String> docIdList = new ArrayList<String>(
+                            urlList.size());
+                    for (final Map<String, Object> doc : docList) {
+                        final Object urlObj = doc.get("url");
+                        if (urlObj != null
+                                && urlList.contains(urlObj.toString())) {
+                            final Object docIdObj = doc.get(Constants.DOC_ID);
+                            if (docIdObj != null) {
+                                docIdList.add(docIdObj.toString());
+                            }
+                        }
+                    }
+
                     final StringBuilder buf = new StringBuilder();
                     final StringBuilder buf = new StringBuilder();
-                    buf.append("\"num\":").append(urls.length);
-                    if (urls.length > 0) {
-                        buf.append(", \"urls\":[");
-                        for (int i = 0; i < urls.length; i++) {
+                    buf.append("\"num\":").append(docIdList.size());
+                    if (!docIdList.isEmpty()) {
+                        buf.append(", \"docIds\":[");
+                        for (int i = 0; i < docIdList.size(); i++) {
                             if (i > 0) {
                             if (i > 0) {
                                 buf.append(',');
                                 buf.append(',');
                             }
                             }
                             buf.append('"');
                             buf.append('"');
-                            buf.append(escapeJsonString(urls[i]));
+                            buf.append(docIdList.get(i));
                             buf.append('"');
                             buf.append('"');
                         }
                         }
                         buf.append(']');
                         buf.append(']');
@@ -1986,40 +2030,35 @@ public class IndexAction {
 
 
     @Execute(validator = false)
     @Execute(validator = false)
     public String screenshot() {
     public String screenshot() {
-        if (StringUtil.isBlank(indexForm.queryId)
-                || StringUtil.isBlank(indexForm.u) || screenShotManager == null) {
-            // 404
-            try {
+        OutputStream out = null;
+        BufferedInputStream in = null;
+        try {
+            final Map<String, Object> doc = searchService.getDocument("docId:"
+                    + indexForm.docId);
+            final String url = doc == null ? null : (String) doc.get("url");
+            if (StringUtil.isBlank(indexForm.queryId)
+                    || StringUtil.isBlank(url) || screenShotManager == null) {
+                // 404
                 response.sendError(HttpServletResponse.SC_NOT_FOUND);
                 response.sendError(HttpServletResponse.SC_NOT_FOUND);
-            } catch (final IOException e) {
-                throw new IORuntimeException(e);
+                return null;
             }
             }
-            return null;
-        }
 
 
-        final File screenShotFile = screenShotManager.getScreenShotFile(
-                indexForm.queryId, indexForm.u);
-        if (screenShotFile == null) {
-            // 404
-            try {
+            final File screenShotFile = screenShotManager.getScreenShotFile(
+                    indexForm.queryId, url);
+            if (screenShotFile == null) {
+                // 404
                 response.sendError(HttpServletResponse.SC_NOT_FOUND);
                 response.sendError(HttpServletResponse.SC_NOT_FOUND);
-            } catch (final IOException e) {
-                throw new IORuntimeException(e);
+                return null;
             }
             }
-            return null;
-        }
 
 
-        response.setContentType(getImageMimeType(screenShotFile));
+            response.setContentType(getImageMimeType(screenShotFile));
 
 
-        OutputStream out = null;
-        BufferedInputStream in = null;
-        try {
             out = response.getOutputStream();
             out = response.getOutputStream();
             in = new BufferedInputStream(new FileInputStream(screenShotFile));
             in = new BufferedInputStream(new FileInputStream(screenShotFile));
             InputStreamUtil.copy(in, out);
             InputStreamUtil.copy(in, out);
             OutputStreamUtil.flush(out);
             OutputStreamUtil.flush(out);
-        } catch (final IOException e) {
-            throw new IORuntimeException(e);
+        } catch (final Exception e) {
+            logger.error("Failed to response: " + indexForm.docId, e);
         } finally {
         } finally {
             IOUtils.closeQuietly(in);
             IOUtils.closeQuietly(in);
             IOUtils.closeQuietly(out);
             IOUtils.closeQuietly(out);

+ 1 - 1
src/main/java/jp/sf/fess/action/MobileAction.java

@@ -144,7 +144,7 @@ public class MobileAction {
         final int pageNum = Integer.parseInt(mobileForm.num);
         final int pageNum = Integer.parseInt(mobileForm.num);
         // TODO add GeoInfo if needed...
         // TODO add GeoInfo if needed...
         try {
         try {
-            documentItems = searchService.selectList(mobileForm.query, null,
+            documentItems = searchService.getDocumentList(mobileForm.query, null,
                     pageStart, pageNum, null, null);
                     pageStart, pageNum, null, null);
         } catch (final InvalidQueryException e) {
         } catch (final InvalidQueryException e) {
             if (logger.isDebugEnabled()) {
             if (logger.isDebugEnabled()) {

+ 1 - 1
src/main/java/jp/sf/fess/action/admin/SearchListAction.java

@@ -150,7 +150,7 @@ public class SearchListAction implements Serializable {
         final int offset = Integer.parseInt(searchListForm.start);
         final int offset = Integer.parseInt(searchListForm.start);
         final int size = Integer.parseInt(searchListForm.num);
         final int size = Integer.parseInt(searchListForm.num);
         try {
         try {
-            documentItems = searchService.selectList(query, null, offset, size,
+            documentItems = searchService.getDocumentList(query, null, offset, size,
                     null, null, false);
                     null, null, false);
         } catch (final InvalidQueryException e) {
         } catch (final InvalidQueryException e) {
             if (logger.isDebugEnabled()) {
             if (logger.isDebugEnabled()) {

+ 2 - 2
src/main/java/jp/sf/fess/ds/impl/AbstractDataStoreImpl.java

@@ -83,8 +83,8 @@ public abstract class AbstractDataStoreImpl implements DataStore {
         }
         }
         // segment
         // segment
         defaultDataMap.put("segment", initParamMap.get(Constants.SESSION_ID));
         defaultDataMap.put("segment", initParamMap.get(Constants.SESSION_ID));
-        // tstamp
-        defaultDataMap.put("tstamp", "NOW");
+        // created
+        defaultDataMap.put("created", "NOW");
         // boost
         // boost
         defaultDataMap.put("boost", config.getBoost().toString());
         defaultDataMap.put("boost", config.getBoost().toString());
         // type: browserType
         // type: browserType

+ 39 - 22
src/main/java/jp/sf/fess/ds/impl/IndexUpdateCallbackImpl.java

@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicLong;
 
 
+import jp.sf.fess.Constants;
 import jp.sf.fess.FessSystemException;
 import jp.sf.fess.FessSystemException;
 import jp.sf.fess.db.bsbhv.BsFavoriteLogBhv;
 import jp.sf.fess.db.bsbhv.BsFavoriteLogBhv;
 import jp.sf.fess.db.cbean.ClickLogCB;
 import jp.sf.fess.db.cbean.ClickLogCB;
@@ -30,6 +31,7 @@ import jp.sf.fess.db.exbhv.pmbean.FavoriteUrlCountPmb;
 import jp.sf.fess.db.exentity.customize.FavoriteUrlCount;
 import jp.sf.fess.db.exentity.customize.FavoriteUrlCount;
 import jp.sf.fess.ds.IndexUpdateCallback;
 import jp.sf.fess.ds.IndexUpdateCallback;
 import jp.sf.fess.helper.CrawlingSessionHelper;
 import jp.sf.fess.helper.CrawlingSessionHelper;
+import jp.sf.fess.helper.SystemHelper;
 
 
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.SolrInputDocument;
 import org.codelibs.solr.lib.SolrGroup;
 import org.codelibs.solr.lib.SolrGroup;
@@ -83,28 +85,7 @@ public class IndexUpdateCallbackImpl implements IndexUpdateCallback {
                 .getComponent(CrawlingSessionHelper.class);
                 .getComponent(CrawlingSessionHelper.class);
         dataMap.put("id", crawlingSessionHelper.generateId(dataMap));
         dataMap.put("id", crawlingSessionHelper.generateId(dataMap));
 
 
-        final SolrInputDocument doc = new SolrInputDocument();
-        for (final Map.Entry<String, Object> entry : dataMap.entrySet()) {
-            if ("boost".equals(entry.getKey())) {
-                // boost
-                final float documentBoost = Float.valueOf(entry.getValue()
-                        .toString());
-                doc.setDocumentBoost(documentBoost);
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Set a document boost (" + documentBoost
-                            + ").");
-                }
-            }
-            doc.addField(entry.getKey(), entry.getValue());
-        }
-
-        if (clickCountEnabled) {
-            addClickCountField(doc, urlObj.toString());
-        }
-
-        if (favoriteCountEnabled) {
-            addFavoriteCountField(doc, urlObj.toString());
-        }
+        final SolrInputDocument doc = createSolrDocument(dataMap);
 
 
         docList.add(doc);
         docList.add(doc);
         if (logger.isDebugEnabled()) {
         if (logger.isDebugEnabled()) {
@@ -133,6 +114,42 @@ public class IndexUpdateCallbackImpl implements IndexUpdateCallback {
         return true;
         return true;
     }
     }
 
 
+    protected SolrInputDocument createSolrDocument(
+            final Map<String, Object> dataMap) {
+        final String url = dataMap.get("url").toString();
+
+        final SolrInputDocument doc = new SolrInputDocument();
+        for (final Map.Entry<String, Object> entry : dataMap.entrySet()) {
+            if ("boost".equals(entry.getKey())) {
+                // boost
+                final float documentBoost = Float.valueOf(entry.getValue()
+                        .toString());
+                doc.setDocumentBoost(documentBoost);
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Set a document boost (" + documentBoost
+                            + ").");
+                }
+            }
+            doc.addField(entry.getKey(), entry.getValue());
+        }
+
+        if (clickCountEnabled) {
+            addClickCountField(doc, url);
+        }
+
+        if (favoriteCountEnabled) {
+            addFavoriteCountField(doc, url);
+        }
+
+        if (!dataMap.containsKey(Constants.DOC_ID)) {
+            final SystemHelper systemHelper = SingletonS2Container
+                    .getComponent(SystemHelper.class);
+            doc.addField(Constants.DOC_ID, systemHelper.generateDocId(dataMap));
+        }
+
+        return doc;
+    }
+
     @Override
     @Override
     public void commit() {
     public void commit() {
         if (!docList.isEmpty()) {
         if (!docList.isEmpty()) {

+ 2 - 2
src/main/java/jp/sf/fess/form/IndexForm.java

@@ -60,8 +60,8 @@ public class IndexForm implements Serializable {
     public String rt;
     public String rt;
 
 
     @Required(target = "go")
     @Required(target = "go")
-    @Maxbytelength(maxbytelength = 4000)
-    public String u;
+    @Maxbytelength(maxbytelength = 100)
+    public String docId;
 
 
     // xml/json
     // xml/json
 
 

+ 11 - 0
src/main/java/jp/sf/fess/helper/SystemHelper.java

@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
+import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 
@@ -116,6 +117,8 @@ public class SystemHelper implements Serializable {
 
 
     private final AtomicBoolean forceStop = new AtomicBoolean(false);
     private final AtomicBoolean forceStop = new AtomicBoolean(false);
 
 
+    private final int maxTextLength = 4000;
+
     @InitMethod
     @InitMethod
     public void init() {
     public void init() {
         final File[] files = ResourceUtil.getJarFiles(launcherFileNamePrefix);
         final File[] files = ResourceUtil.getJarFiles(launcherFileNamePrefix);
@@ -624,4 +627,12 @@ public class SystemHelper implements Serializable {
         return runningJobExecutorMap.get(id);
         return runningJobExecutorMap.get(id);
     }
     }
 
 
+    public String generateDocId(final Map<String, Object> map) {
+        return UUID.randomUUID().toString().replace("-", "");
+    }
+
+    public String abbreviateLongText(final String str) {
+        return StringUtils.abbreviate(str, maxTextLength);
+    }
+
 }
 }

+ 1 - 1
src/main/java/jp/sf/fess/helper/UserInfoHelper.java

@@ -25,6 +25,6 @@ public interface UserInfoHelper {
 
 
     String generateQueryId(String query, List<Map<String, Object>> documentItems);
     String generateQueryId(String query, List<Map<String, Object>> documentItems);
 
 
-    String[] getResultUrls(String decode);
+    String[] getResultDocIds(String queryId);
 
 
 }
 }

+ 24 - 24
src/main/java/jp/sf/fess/helper/impl/CookieUserInfoHelperImpl.java

@@ -20,6 +20,7 @@ import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.UUID;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.Cookie;
@@ -33,7 +34,6 @@ import jp.sf.fess.service.UserInfoService;
 
 
 import org.seasar.framework.container.annotation.tiger.InitMethod;
 import org.seasar.framework.container.annotation.tiger.InitMethod;
 import org.seasar.framework.util.StringUtil;
 import org.seasar.framework.util.StringUtil;
-import org.seasar.framework.util.UUID;
 import org.seasar.robot.util.LruHashMap;
 import org.seasar.robot.util.LruHashMap;
 import org.seasar.struts.util.RequestUtil;
 import org.seasar.struts.util.RequestUtil;
 import org.seasar.struts.util.ResponseUtil;
 import org.seasar.struts.util.ResponseUtil;
@@ -45,7 +45,7 @@ public class CookieUserInfoHelperImpl implements UserInfoHelper {
 
 
     public int userInfoCacheSize = 1000;
     public int userInfoCacheSize = 1000;
 
 
-    public int resultUrlCacheSize = 10;
+    public int resultDocIdsCacheSize = 20;
 
 
     public String cookieName = "fsid";
     public String cookieName = "fsid";
 
 
@@ -90,7 +90,7 @@ public class CookieUserInfoHelperImpl implements UserInfoHelper {
     }
     }
 
 
     protected String getId() {
     protected String getId() {
-        return UUID.create();
+        return UUID.randomUUID().toString().replace("-", "");
     }
     }
 
 
     protected void updateUserSessionId(final String userCode) {
     protected void updateUserSessionId(final String userCode) {
@@ -143,22 +143,20 @@ public class CookieUserInfoHelperImpl implements UserInfoHelper {
             final List<Map<String, Object>> documentItems) {
             final List<Map<String, Object>> documentItems) {
         final HttpSession session = RequestUtil.getRequest().getSession(false);
         final HttpSession session = RequestUtil.getRequest().getSession(false);
         if (session != null) {
         if (session != null) {
-            String queryId = query.hashCode() + session.getId()
-                    + System.currentTimeMillis();
-            queryId = Integer.toString(queryId.hashCode());
+            final String queryId = getId();
 
 
-            final List<String> urlList = new ArrayList<String>();
+            final List<String> docIdList = new ArrayList<String>();
             for (final Map<String, Object> map : documentItems) {
             for (final Map<String, Object> map : documentItems) {
-                final Object url = map.get("url");
-                if (url != null && url.toString().length() > 0) {
-                    urlList.add(url.toString());
+                final Object docId = map.get(Constants.DOC_ID);
+                if (docId != null && docId.toString().length() > 0) {
+                    docIdList.add(docId.toString());
                 }
                 }
             }
             }
 
 
-            if (!urlList.isEmpty()) {
-                final Map<String, String[]> resultUrlCache = getResultUrlCache(session);
-                resultUrlCache.put(queryId,
-                        urlList.toArray(new String[urlList.size()]));
+            if (!docIdList.isEmpty()) {
+                final Map<String, String[]> resultDocIdsCache = getResultDocIdsCache(session);
+                resultDocIdsCache.put(queryId,
+                        docIdList.toArray(new String[docIdList.size()]));
                 return queryId;
                 return queryId;
             }
             }
         }
         }
@@ -166,10 +164,10 @@ public class CookieUserInfoHelperImpl implements UserInfoHelper {
     }
     }
 
 
     @Override
     @Override
-    public String[] getResultUrls(final String queryId) {
+    public String[] getResultDocIds(final String queryId) {
         final HttpSession session = RequestUtil.getRequest().getSession(false);
         final HttpSession session = RequestUtil.getRequest().getSession(false);
         if (session != null) {
         if (session != null) {
-            final Map<String, String[]> resultUrlCache = getResultUrlCache(session);
+            final Map<String, String[]> resultUrlCache = getResultDocIdsCache(session);
             final String[] urls = resultUrlCache.get(queryId);
             final String[] urls = resultUrlCache.get(queryId);
             if (urls != null) {
             if (urls != null) {
                 return urls;
                 return urls;
@@ -178,14 +176,16 @@ public class CookieUserInfoHelperImpl implements UserInfoHelper {
         return new String[0];
         return new String[0];
     }
     }
 
 
-    private Map<String, String[]> getResultUrlCache(final HttpSession session) {
-        Map<String, String[]> resultUrlCache = (Map<String, String[]>) session
-                .getAttribute(Constants.RESULT_URL_CACHE);
-        if (resultUrlCache == null) {
-            resultUrlCache = new LruHashMap<String, String[]>(
-                    resultUrlCacheSize);
-            session.setAttribute(Constants.RESULT_URL_CACHE, resultUrlCache);
+    private Map<String, String[]> getResultDocIdsCache(final HttpSession session) {
+        @SuppressWarnings("unchecked")
+        Map<String, String[]> resultDocIdsCache = (Map<String, String[]>) session
+                .getAttribute(Constants.RESULT_DOC_ID_CACHE);
+        if (resultDocIdsCache == null) {
+            resultDocIdsCache = new LruHashMap<String, String[]>(
+                    resultDocIdsCacheSize);
+            session.setAttribute(Constants.RESULT_DOC_ID_CACHE,
+                    resultDocIdsCache);
         }
         }
-        return resultUrlCache;
+        return resultDocIdsCache;
     }
     }
 }
 }

+ 7 - 7
src/main/java/jp/sf/fess/helper/impl/QueryHelperImpl.java

@@ -77,16 +77,16 @@ public class QueryHelperImpl implements QueryHelper, Serializable {
     @Resource
     @Resource
     protected RoleQueryHelper roleQueryHelper;
     protected RoleQueryHelper roleQueryHelper;
 
 
-    protected String[] responseFields = new String[] { "id", "score", "boost",
-            "contentLength", "host", "site", "lastModified", "mimetype",
-            "tstamp", "title", "digest", "url", "clickCount_i",
+    protected String[] responseFields = new String[] { "id", "docId", "score",
+            "boost", "contentLength", "host", "site", "lastModified",
+            "mimetype", "created", "title", "digest", "url", "clickCount_i",
             "favoriteCount_i", "screenshot_s_s" };
             "favoriteCount_i", "screenshot_s_s" };
 
 
     protected String[] highlightingFields = new String[] { "content" };
     protected String[] highlightingFields = new String[] { "content" };
 
 
-    protected String[] searchFields = new String[] { "url", "host", "title",
-            "content", "contentLength", "lastModified", "mimetype", "label",
-            "segment", "clickCount_i", "favoriteCount_i", "inurl" };
+    protected String[] searchFields = new String[] { "url", "docId", "host",
+            "title", "content", "contentLength", "lastModified", "mimetype",
+            "label", "segment", "clickCount_i", "favoriteCount_i", "inurl" };
 
 
     protected String[] facetFields = new String[] { "url", "host", "title",
     protected String[] facetFields = new String[] { "url", "host", "title",
             "content", "contentLength", "lastModified", "mimetype", "label",
             "content", "contentLength", "lastModified", "mimetype", "label",
@@ -94,7 +94,7 @@ public class QueryHelperImpl implements QueryHelper, Serializable {
 
 
     protected String sortPrefix = "sort:";
     protected String sortPrefix = "sort:";
 
 
-    protected String[] supportedSortFields = new String[] { "tstamp",
+    protected String[] supportedSortFields = new String[] { "created",
             "contentLength", "lastModified", "clickCount_i", "favoriteCount_i" };
             "contentLength", "lastModified", "clickCount_i", "favoriteCount_i" };
 
 
     protected String[] supportedMltFields = new String[] { "content",
     protected String[] supportedMltFields = new String[] { "content",

+ 2 - 1
src/main/java/jp/sf/fess/job/TriggeredJob.java

@@ -91,7 +91,8 @@ public class TriggeredJob implements Job {
         } catch (final Throwable e) {
         } catch (final Throwable e) {
             logger.error("Failed to execute " + jobId + ": " + script, e);
             logger.error("Failed to execute " + jobId + ": " + script, e);
             jobLog.setJobStatus(Constants.FAIL);
             jobLog.setJobStatus(Constants.FAIL);
-            jobLog.setScriptResult(e.getLocalizedMessage());
+            jobLog.setScriptResult(systemHelper.abbreviateLongText(e
+                    .getLocalizedMessage()));
         } finally {
         } finally {
             systemHelper.finishJobExecutoer(id);
             systemHelper.finishJobExecutoer(id);
             jobLog.setEndTime(new Timestamp(System.currentTimeMillis()));
             jobLog.setEndTime(new Timestamp(System.currentTimeMillis()));

+ 10 - 11
src/main/java/jp/sf/fess/service/FavoriteLogService.java

@@ -22,6 +22,7 @@ import java.io.Writer;
 import java.sql.Timestamp;
 import java.sql.Timestamp;
 import java.text.ParseException;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
@@ -115,9 +116,10 @@ public class FavoriteLogService extends BsFavoriteLogService implements
         return false;
         return false;
     }
     }
 
 
-    public String[] getUrls(final String userCode, final String[] urls) {
-        if (urls.length == 0) {
-            return urls;
+    public List<String> getUrlList(final String userCode,
+            final List<String> urlList) {
+        if (urlList.isEmpty()) {
+            return urlList;
         }
         }
 
 
         final UserInfoCB cb = new UserInfoCB();
         final UserInfoCB cb = new UserInfoCB();
@@ -125,10 +127,6 @@ public class FavoriteLogService extends BsFavoriteLogService implements
         final UserInfo userInfo = userInfoBhv.selectEntity(cb);
         final UserInfo userInfo = userInfoBhv.selectEntity(cb);
 
 
         if (userInfo != null) {
         if (userInfo != null) {
-            final List<String> urlList = new ArrayList<String>();
-            for (final String url : urls) {
-                urlList.add(url);
-            }
             final FavoriteLogCB cb2 = new FavoriteLogCB();
             final FavoriteLogCB cb2 = new FavoriteLogCB();
             cb2.query().setUserId_Equal(userInfo.getId());
             cb2.query().setUserId_Equal(userInfo.getId());
             cb2.query().setUrl_InScope(urlList);
             cb2.query().setUrl_InScope(urlList);
@@ -136,15 +134,16 @@ public class FavoriteLogService extends BsFavoriteLogService implements
             final ListResultBean<FavoriteLog> list = favoriteLogBhv
             final ListResultBean<FavoriteLog> list = favoriteLogBhv
                     .selectList(cb2);
                     .selectList(cb2);
             if (!list.isEmpty()) {
             if (!list.isEmpty()) {
-                urlList.clear();
+                final List<String> newUrlList = new ArrayList<String>(
+                        list.size());
                 for (final FavoriteLog favoriteLog : list) {
                 for (final FavoriteLog favoriteLog : list) {
-                    urlList.add(favoriteLog.getUrl());
+                    newUrlList.add(favoriteLog.getUrl());
                 }
                 }
-                return urlList.toArray(new String[urlList.size()]);
+                return newUrlList;
             }
             }
         }
         }
 
 
-        return new String[0];
+        return Collections.emptyList();
     }
     }
 
 
     public void deleteAll(final FavoriteLogPager favoriteLogPager) {
     public void deleteAll(final FavoriteLogPager favoriteLogPager) {

+ 30 - 3
src/main/java/jp/sf/fess/service/SearchService.java

@@ -17,6 +17,7 @@
 package jp.sf.fess.service;
 package jp.sf.fess.service;
 
 
 import java.io.Serializable;
 import java.io.Serializable;
+import java.util.Collections;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Map.Entry;
@@ -59,13 +60,39 @@ public class SearchService implements Serializable {
     @Resource
     @Resource
     protected QueryHelper queryHelper;
     protected QueryHelper queryHelper;
 
 
-    public List<Map<String, Object>> selectList(final String query,
+    public Map<String, Object> getDocument(final String query) {
+        final List<Map<String, Object>> docList = getDocumentList(query, null,
+                0, 1, null, null);
+        if (!docList.isEmpty()) {
+            return docList.get(0);
+        }
+        return null;
+    }
+
+    public List<Map<String, Object>> getDocumentListByDocIds(
+            final String[] docIds, final int pageSize) {
+        if (docIds == null || docIds.length == 0) {
+            return Collections.emptyList();
+        }
+
+        final StringBuilder buf = new StringBuilder(1000);
+        for (int i = 0; i < docIds.length; i++) {
+            if (i != 0) {
+                buf.append(" OR ");
+            }
+            buf.append("docId:").append(docIds[i]);
+        }
+        return getDocumentList(buf.toString(), null, 0, pageSize, null, null);
+    }
+
+    public List<Map<String, Object>> getDocumentList(final String query,
             final FacetInfo facetInfo, final int start, final int rows,
             final FacetInfo facetInfo, final int start, final int rows,
             final GeoInfo geoInfo, final MoreLikeThisInfo mltInfo) {
             final GeoInfo geoInfo, final MoreLikeThisInfo mltInfo) {
-        return selectList(query, facetInfo, start, rows, geoInfo, mltInfo, true);
+        return getDocumentList(query, facetInfo, start, rows, geoInfo, mltInfo,
+                true);
     }
     }
 
 
-    public List<Map<String, Object>> selectList(final String query,
+    public List<Map<String, Object>> getDocumentList(final String query,
             final FacetInfo facetInfo, final int start, final int rows,
             final FacetInfo facetInfo, final int start, final int rows,
             final GeoInfo geoInfo, final MoreLikeThisInfo mltInfo,
             final GeoInfo geoInfo, final MoreLikeThisInfo mltInfo,
             final boolean forUser) {
             final boolean forUser) {

+ 4 - 0
src/main/java/jp/sf/fess/solr/IndexUpdater.java

@@ -474,6 +474,10 @@ public class IndexUpdater extends Thread {
             addBoostValue(map, documentBoost, doc);
             addBoostValue(map, documentBoost, doc);
         }
         }
 
 
+        if (!map.containsKey(Constants.DOC_ID)) {
+            doc.addField(Constants.DOC_ID, systemHelper.generateDocId(map));
+        }
+
         return doc;
         return doc;
     }
     }
 
 

+ 2 - 2
src/main/java/jp/sf/fess/transformer/AbstractFessFileTransformer.java

@@ -250,8 +250,8 @@ public abstract class AbstractFessFileTransformer extends
                 getSite(url, responseData.getCharSet()));
                 getSite(url, responseData.getCharSet()));
         // url
         // url
         putResultDataBody(dataMap, "url", url);
         putResultDataBody(dataMap, "url", url);
-        // tstamp
-        putResultDataBody(dataMap, "tstamp", "NOW");
+        // created
+        putResultDataBody(dataMap, "created", "NOW");
         // TODO anchor
         // TODO anchor
         putResultDataBody(dataMap, "anchor", "");
         putResultDataBody(dataMap, "anchor", "");
         // mimetype
         // mimetype

+ 2 - 4
src/main/java/jp/sf/fess/transformer/FessXpathTransformer.java

@@ -251,8 +251,8 @@ public class FessXpathTransformer extends AbstractFessXpathTransformer {
                 getSite(url, responseData.getCharSet()));
                 getSite(url, responseData.getCharSet()));
         // url
         // url
         putResultDataBody(dataMap, "url", url);
         putResultDataBody(dataMap, "url", url);
-        // tstamp
-        putResultDataBody(dataMap, "tstamp", "NOW");
+        // created
+        putResultDataBody(dataMap, "created", "NOW");
         // anchor
         // anchor
         putResultDataBody(dataMap, "anchor",
         putResultDataBody(dataMap, "anchor",
                 getAnchorList(document, responseData));
                 getAnchorList(document, responseData));
@@ -290,8 +290,6 @@ public class FessXpathTransformer extends AbstractFessXpathTransformer {
             roleTypeList.add(roleType);
             roleTypeList.add(roleType);
         }
         }
         putResultDataBody(dataMap, "role", roleTypeList);
         putResultDataBody(dataMap, "role", roleTypeList);
-        // TODO date
-        // TODO lang
         // id
         // id
         putResultDataBody(dataMap, "id",
         putResultDataBody(dataMap, "id",
                 crawlingSessionHelper.generateId(dataMap));
                 crawlingSessionHelper.generateId(dataMap));

+ 4 - 4
src/main/resources/app.dicon

@@ -57,19 +57,19 @@
 		</initMethod>
 		</initMethod>
 		<!-- 
 		<!-- 
 		<property name="additionalGeoQuery">"location_i_i:1"</property>
 		<property name="additionalGeoQuery">"location_i_i:1"</property>
-		<property name="responseFields">new String[]{"id", "score", "boost",
+		<property name="responseFields">new String[]{"id", "docId", "score", "boost",
             "contentLength", "host", "site", "lastModified", "mimetype",
             "contentLength", "host", "site", "lastModified", "mimetype",
-            "tstamp", "title", "digest", "url", "clickCount_i", "favoriteCount_i",
+            "created", "title", "digest", "url", "clickCount_i", "favoriteCount_i",
             "screenshot_s_s"}</property>
             "screenshot_s_s"}</property>
 		<property name="highlightingFields">new String[]{"digest", "cache" }</property>
 		<property name="highlightingFields">new String[]{"digest", "cache" }</property>
-		<property name="searchFields">new String[]{"url", "host", 
+		<property name="searchFields">new String[]{"url", "docId", "host", 
             "title", "content", "contentLength", "lastModified", "mimetype",
             "title", "content", "contentLength", "lastModified", "mimetype",
             "label", "segment" }</property>
             "label", "segment" }</property>
 		<property name="facetFields">new String[]{"url", "host", 
 		<property name="facetFields">new String[]{"url", "host", 
             "title", "content", "contentLength", "lastModified", "mimetype",
             "title", "content", "contentLength", "lastModified", "mimetype",
             "label", "segment" }</property>
             "label", "segment" }</property>
 		<property name="sortPrefix">"sort:"</property>
 		<property name="sortPrefix">"sort:"</property>
-		<property name="supportedSortFields">new String[]{"tstamp",
+		<property name="supportedSortFields">new String[]{"created",
             "contentLength", "lastModified", "clickCount_i" }</property>
             "contentLength", "lastModified", "clickCount_i" }</property>
 		<property name="supportedMltFields">new String[]{"content",
 		<property name="supportedMltFields">new String[]{"content",
             "content_ja" }</property>
             "content_ja" }</property>

+ 5 - 3
src/main/resources/application.properties

@@ -66,6 +66,8 @@ errors.failed_to_delete_file=Failed to delete {0} file.
 errors.failed_to_redirect=Failed to redirect {0}.
 errors.failed_to_redirect=Failed to redirect {0}.
 errors.no_launcher_applet_jar=No launcher file.
 errors.no_launcher_applet_jar=No launcher file.
 errors.unsupported_encoding={0} is not supported as encoding.
 errors.unsupported_encoding={0} is not supported as encoding.
+errors.docid_not_found=Not found Doc ID:{0}
+errors.document_not_found=Not found URL of Doc ID:{0}
 
 
 errors.invalid_query_unknown=The given query is invalid.
 errors.invalid_query_unknown=The given query is invalid.
 errors.invalid_query_quoted=An invalid quote character is used.
 errors.invalid_query_quoted=An invalid quote character is used.
@@ -331,14 +333,14 @@ labels.search_title=Fess
 labels.search_hot_search_word=Hot Keywords: 
 labels.search_hot_search_word=Hot Keywords: 
 labels.search_result_select_sort=-- Sort --
 labels.search_result_select_sort=-- Sort --
 labels.search_result_select_num=-- Results per page --
 labels.search_result_select_num=-- Results per page --
-labels.search_result_sort_tstamp_asc=Date (ascending)
-labels.search_result_sort_tstamp_desc=Date (descending)
+labels.search_result_sort_created_asc=Date (ascending)
+labels.search_result_sort_created_desc=Date (descending)
 labels.search_result_sort_contentLength_asc=Size (ascending)
 labels.search_result_sort_contentLength_asc=Size (ascending)
 labels.search_result_sort_contentLength_desc=Size (descending)
 labels.search_result_sort_contentLength_desc=Size (descending)
 labels.search_result_sort_lastModified_asc=Last Modified (ascending)
 labels.search_result_sort_lastModified_asc=Last Modified (ascending)
 labels.search_result_sort_lastModified_desc=Last Modified (descending)
 labels.search_result_sort_lastModified_desc=Last Modified (descending)
 labels.search_result_size={0} bytes
 labels.search_result_size={0} bytes
-labels.search_result_tstamp=Registered: 
+labels.search_result_created=Registered: 
 labels.search_result_lastModified=Last Modified: 
 labels.search_result_lastModified=Last Modified: 
 labels.search_result_favorite=Vote it
 labels.search_result_favorite=Vote it
 labels.search_result_favorited=Voted
 labels.search_result_favorited=Voted

+ 5 - 3
src/main/resources/application_ja.properties

@@ -66,6 +66,8 @@ errors.failed_to_delete_file=\u30d5\u30a1\u30a4\u30eb {0} \u306e\u524a\u9664\u30
 errors.failed_to_redirect={0}\u3078\u306e\u30ea\u30c0\u30a4\u30ec\u30af\u30c8\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
 errors.failed_to_redirect={0}\u3078\u306e\u30ea\u30c0\u30a4\u30ec\u30af\u30c8\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
 errors.no_launcher_applet_jar=\u8d77\u52d5\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002
 errors.no_launcher_applet_jar=\u8d77\u52d5\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308a\u307e\u305b\u3093\u3002
 errors.unsupported_encoding={0}\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u3067\u3059\u3002
 errors.unsupported_encoding={0}\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u306a\u3044\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u3067\u3059\u3002
+errors.docid_not_found=ID:{0}\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002
+errors.document_not_found=ID:{0}\u306eURL\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002
 
 
 errors.invalid_query_unknown=\u691c\u7d22\u30af\u30a8\u30ea\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002
 errors.invalid_query_unknown=\u691c\u7d22\u30af\u30a8\u30ea\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002
 errors.invalid_query_quoted=\u30af\u30aa\u30fc\u30c8\u6587\u5b57(")\u306e\u5229\u7528\u65b9\u6cd5\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002
 errors.invalid_query_quoted=\u30af\u30aa\u30fc\u30c8\u6587\u5b57(")\u306e\u5229\u7528\u65b9\u6cd5\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002
@@ -331,14 +333,14 @@ labels.search_title=Fess
 labels.search_hot_search_word=\u6ce8\u76ee\u30ad\u30fc\u30ef\u30fc\u30c9: 
 labels.search_hot_search_word=\u6ce8\u76ee\u30ad\u30fc\u30ef\u30fc\u30c9: 
 labels.search_result_select_sort=-- \u30bd\u30fc\u30c8 --
 labels.search_result_select_sort=-- \u30bd\u30fc\u30c8 --
 labels.search_result_select_num=-- \u8868\u793a\u4ef6\u6570 --
 labels.search_result_select_num=-- \u8868\u793a\u4ef6\u6570 --
-labels.search_result_sort_tstamp_asc=\u767b\u9332\u65e5\u6642 (\u6607\u9806)
-labels.search_result_sort_tstamp_desc=\u767b\u9332\u65e5\u6642 (\u964d\u9806)
+labels.search_result_sort_created_asc=\u767b\u9332\u65e5\u6642 (\u6607\u9806)
+labels.search_result_sort_created_desc=\u767b\u9332\u65e5\u6642 (\u964d\u9806)
 labels.search_result_sort_contentLength_asc=\u30b5\u30a4\u30ba (\u6607\u9806)
 labels.search_result_sort_contentLength_asc=\u30b5\u30a4\u30ba (\u6607\u9806)
 labels.search_result_sort_contentLength_desc=\u30b5\u30a4\u30ba (\u964d\u9806)
 labels.search_result_sort_contentLength_desc=\u30b5\u30a4\u30ba (\u964d\u9806)
 labels.search_result_sort_lastModified_asc=\u66f4\u65b0\u65e5\u6642 (\u6607\u9806)
 labels.search_result_sort_lastModified_asc=\u66f4\u65b0\u65e5\u6642 (\u6607\u9806)
 labels.search_result_sort_lastModified_desc=\u66f4\u65b0\u65e5\u6642 (\u964d\u9806)
 labels.search_result_sort_lastModified_desc=\u66f4\u65b0\u65e5\u6642 (\u964d\u9806)
 labels.search_result_size={0} \u30d0\u30a4\u30c8
 labels.search_result_size={0} \u30d0\u30a4\u30c8
-labels.search_result_tstamp=\u767b\u9332\u65e5\u6642: 
+labels.search_result_created=\u767b\u9332\u65e5\u6642: 
 labels.search_result_lastModified=\u66f4\u65b0\u65e5\u6642: 
 labels.search_result_lastModified=\u66f4\u65b0\u65e5\u6642: 
 labels.search_result_favorite=1\u7968\u5165\u308c\u308b
 labels.search_result_favorite=1\u7968\u5165\u308c\u308b
 labels.search_result_favorited=\u6295\u7968\u6e08\u307f
 labels.search_result_favorited=\u6295\u7968\u6e08\u307f

+ 1 - 1
src/main/webapp/WEB-INF/view/common/help.jsp

@@ -18,7 +18,7 @@
 		desc. If you want to find documents which has "Fess" and sort them in
 		desc. If you want to find documents which has "Fess" and sort them in
 		descending order, you can enter:
 		descending order, you can enter:
 		<pre>Fess sort:contentLength.desc</pre>
 		<pre>Fess sort:contentLength.desc</pre>
-		The available sort field are "tstamp", "contentLength" and
+		The available sort field are "created", "contentLength" and
 		"lastModified", and they are customizable.
 		"lastModified", and they are customizable.
 	</dd>
 	</dd>
 	<dt>AND</dt>
 	<dt>AND</dt>

+ 1 - 1
src/main/webapp/WEB-INF/view/common/help_ja.jsp

@@ -17,7 +17,7 @@
 		&lt;order&gt; は asc または desc で昇順・降順を指定できます。
 		&lt;order&gt; は asc または desc で昇順・降順を指定できます。
 		たとえば、Fess を含むドキュメントでサイズの降順にソートしたい場合、次のように入力します。
 		たとえば、Fess を含むドキュメントでサイズの降順にソートしたい場合、次のように入力します。
 		<pre>Fess sort:contentLength.desc</pre>
 		<pre>Fess sort:contentLength.desc</pre>
-		標準で利用可能なフィールドは tstamp, contentLength および lastModified になります。
+		標準で利用可能なフィールドは created, contentLength および lastModified になります。
 		設定で指定するフィールドは変更することができます。
 		設定で指定するフィールドは変更することができます。
 	</dd>
 	</dd>
 	<dt>AND検索</dt>
 	<dt>AND検索</dt>

+ 4 - 4
src/main/webapp/WEB-INF/view/error/header.jsp

@@ -59,11 +59,11 @@
 							<option value="">
 							<option value="">
 								<bean:message key="labels.search_result_select_sort" />
 								<bean:message key="labels.search_result_select_sort" />
 							</option>
 							</option>
-							<html:option value="tstamp.asc">
-								<bean:message key="labels.search_result_sort_tstamp_asc" />
+							<html:option value="created.asc">
+								<bean:message key="labels.search_result_sort_created_asc" />
 							</html:option>
 							</html:option>
-							<html:option value="tstamp.desc">
-								<bean:message key="labels.search_result_sort_tstamp_desc" />
+							<html:option value="created.desc">
+								<bean:message key="labels.search_result_sort_created_desc" />
 							</html:option>
 							</html:option>
 							<html:option value="contentLength.asc">
 							<html:option value="contentLength.asc">
 								<bean:message key="labels.search_result_sort_contentLength_asc" />
 								<bean:message key="labels.search_result_sort_contentLength_asc" />

+ 4 - 4
src/main/webapp/WEB-INF/view/header.jsp

@@ -63,11 +63,11 @@ ${fe:facetForm()}${fe:mltForm()}${fe:geoForm()}
 							<option value="">
 							<option value="">
 								<bean:message key="labels.search_result_select_sort" />
 								<bean:message key="labels.search_result_select_sort" />
 							</option>
 							</option>
-							<html:option value="tstamp.asc">
-								<bean:message key="labels.search_result_sort_tstamp_asc" />
+							<html:option value="created.asc">
+								<bean:message key="labels.search_result_sort_created_asc" />
 							</html:option>
 							</html:option>
-							<html:option value="tstamp.desc">
-								<bean:message key="labels.search_result_sort_tstamp_desc" />
+							<html:option value="created.desc">
+								<bean:message key="labels.search_result_sort_created_desc" />
 							</html:option>
 							</html:option>
 							<html:option value="contentLength.asc">
 							<html:option value="contentLength.asc">
 								<bean:message key="labels.search_result_sort_contentLength_asc" />
 								<bean:message key="labels.search_result_sort_contentLength_asc" />

+ 4 - 4
src/main/webapp/WEB-INF/view/index.jsp

@@ -115,11 +115,11 @@
 											<option value="">
 											<option value="">
 												<bean:message key="labels.search_result_select_sort" />
 												<bean:message key="labels.search_result_select_sort" />
 											</option>
 											</option>
-											<html:option value="tstamp.asc">
-												<bean:message key="labels.search_result_sort_tstamp_asc" />
+											<html:option value="created.asc">
+												<bean:message key="labels.search_result_sort_created_asc" />
 											</html:option>
 											</html:option>
-											<html:option value="tstamp.desc">
-												<bean:message key="labels.search_result_sort_tstamp_desc" />
+											<html:option value="created.desc">
+												<bean:message key="labels.search_result_sort_created_desc" />
 											</html:option>
 											</html:option>
 											<html:option value="contentLength.asc">
 											<html:option value="contentLength.asc">
 												<bean:message
 												<bean:message

+ 7 - 8
src/main/webapp/WEB-INF/view/searchResults.jsp

@@ -22,16 +22,15 @@
 	</div>
 	</div>
 </c:if>
 </c:if>
 <div id="result" class="row content">
 <div id="result" class="row content">
-	<input type="hidden" id="queryId" value="${f:u(queryId)}" /> <input
-		type="hidden" id="contextPath" value="<%=request.getContextPath()%>" />
+	<input type="hidden" id="queryId" value="${f:u(queryId)}" />
+	<input type="hidden" id="contextPath" value="<%=request.getContextPath()%>" />
 	<input type="hidden" id="rt" value="${f:u(rt)}" />
 	<input type="hidden" id="rt" value="${f:u(rt)}" />
 	<div class="span8">
 	<div class="span8">
 		<ol>
 		<ol>
 			<c:forEach var="doc" varStatus="s" items="${documentItems}">
 			<c:forEach var="doc" varStatus="s" items="${documentItems}">
 				<li id="result${s.index}">
 				<li id="result${s.index}">
 					<h3 class="title">
 					<h3 class="title">
-						<a href="${doc.urlLink}" class="link">
-							${f:h(doc.contentTitle)} </a>
+						<a class="link" href="${doc.urlLink}" data-uri="${doc.urlLink}" data-id="${doc.docId}">${f:h(doc.contentTitle)}</a>
 					</h3>
 					</h3>
 					<div class="body">
 					<div class="body">
 						<div class="description">${doc.contentDescription}</div>
 						<div class="description">${doc.contentDescription}</div>
@@ -42,9 +41,9 @@
 							<a href="#result${s.index}"><bean:message key="labels.search_result_more" /></a>
 							<a href="#result${s.index}"><bean:message key="labels.search_result_more" /></a>
 						</div>
 						</div>
 						<div class="info">
 						<div class="info">
-							<c:if test="${doc.tstamp!=null && doc.tstamp!=''}">
-								<bean:message key="labels.search_result_tstamp" />
-								<fmt:formatDate value="${fe:parseDate(doc.tstamp)}" type="BOTH" />
+							<c:if test="${doc.created!=null && doc.created!=''}">
+								<bean:message key="labels.search_result_created" />
+								<fmt:formatDate value="${fe:parseDate(doc.created)}" type="BOTH" />
 								<span class="br-phone"></span>
 								<span class="br-phone"></span>
 								<span class="hidden-phone">-</span>
 								<span class="hidden-phone">-</span>
 							</c:if>
 							</c:if>
@@ -62,7 +61,7 @@
 								<span class="hidden-phone">-</span>
 								<span class="hidden-phone">-</span>
 							</c:if>
 							</c:if>
 							<c:if test="${favoriteSupport}">
 							<c:if test="${favoriteSupport}">
-								<a href="#${doc.url}" class="favorite"><bean:message
+								<a href="#${doc.docId}" class="favorite"><bean:message
 										key="labels.search_result_favorite" /></a>
 										key="labels.search_result_favorite" /></a>
 								<span class="favorited"><bean:message
 								<span class="favorited"><bean:message
 										key="labels.search_result_favorited" /></span>
 										key="labels.search_result_favorited" /></span>

+ 19 - 20
src/main/webapp/js/search.js

@@ -21,32 +21,31 @@ $(function(){
 	});
 	});
 
 
 	$result.on('mousedown', 'a.link', function(e){
 	$result.on('mousedown', 'a.link', function(e){
-		var url = $(this).attr('href'),
+		var docId = $(this).attr('data-id'),
 			rt = $('#rt').val(),
 			rt = $('#rt').val(),
 			buf = [];
 			buf = [];
 		buf.push('go?rt=');
 		buf.push('go?rt=');
 		buf.push(rt);
 		buf.push(rt);
-		buf.push('&u=');
-		buf.push(encodeURIComponent(url));
+		buf.push('&docId=');
+		buf.push(docId);
 		$(this).attr('href', buf.join(''));
 		$(this).attr('href', buf.join(''));
 	});
 	});
 
 
 	$result.on('mouseover', 'a.link', function(e){
 	$result.on('mouseover', 'a.link', function(e){
 		if($screenshot.size() > 0) {
 		if($screenshot.size() > 0) {
-			var url = $(this).attr('href'),
+			var docId = $(this).attr('data-id'),
 				rt = $('#rt').val(),
 				rt = $('#rt').val(),
 				queryId = $queryId.val(),
 				queryId = $queryId.val(),
 				buf = [];
 				buf = [];
 			buf.push('go?rt=');
 			buf.push('go?rt=');
 			buf.push(rt);
 			buf.push(rt);
-			buf.push('&u=');
-			buf.push(encodeURIComponent(url));
+			buf.push('&docId=');
+			buf.push(docId);
 
 
 			$screenshot.children().remove();
 			$screenshot.children().remove();
 			
 			
 			var content = '<a href="' + buf.join('') + '"><img src="screenshot?queryId='
 			var content = '<a href="' + buf.join('') + '"><img src="screenshot?queryId='
-				+ queryId + '&u=' + encodeURIComponent(url)
-				+ '"></a>'
+				+ queryId + '&docId=' + docId + '"></a>'
 			$screenshot.append(content);
 			$screenshot.append(content);
 			$('img', $screenshot).error(function() {
 			$('img', $screenshot).error(function() {
 				$screenshot.children().remove();
 				$screenshot.children().remove();
@@ -60,7 +59,7 @@ $(function(){
 		if(values.length === 2 && $queryId.size() > 0){
 		if(values.length === 2 && $queryId.size() > 0){
 			var contextPath = $('#contextPath').val();
 			var contextPath = $('#contextPath').val();
 			var actionUrl = contextPath + '/favorite';
 			var actionUrl = contextPath + '/favorite';
-			var favoriteUrl = values[1];
+			var docId = values[1];
 			$.ajax({
 			$.ajax({
 				dataType: 'json',
 				dataType: 'json',
 				cache: false,
 				cache: false,
@@ -68,18 +67,18 @@ $(function(){
 				timeoutNumber: 10000,
 				timeoutNumber: 10000,
 				url: actionUrl,
 				url: actionUrl,
 				data: {
 				data: {
-					u: favoriteUrl,
+					docId: docId,
 					queryId: $queryId.val()
 					queryId: $queryId.val()
 					}
 					}
 			}).done(function ( data ) {
 			}).done(function ( data ) {
 				if(data.response.status === 0 
 				if(data.response.status === 0 
 					&& typeof data.response.result !== 'undefined'
 					&& typeof data.response.result !== 'undefined'
-					&& data.response.result == 'ok'){
+					&& data.response.result === 'ok'){
 					var $favorited = $favorite.siblings('.favorited');
 					var $favorited = $favorite.siblings('.favorited');
 					$favorite.fadeOut(1000, function(){$favorited.fadeIn(1000)});
 					$favorite.fadeOut(1000, function(){$favorited.fadeIn(1000)});
 				}
 				}
 			}).fail(function ( data ) {
 			}).fail(function ( data ) {
-				$favorite.attr('href', '#' + favoriteUrl);
+				$favorite.attr('href', '#' + docId);
 //alert(JSON.stringify(data));
 //alert(JSON.stringify(data));
 			});
 			});
 		}
 		}
@@ -95,23 +94,23 @@ $(function(){
 			type: 'post',
 			type: 'post',
 			timeoutNumber: 10000,
 			timeoutNumber: 10000,
 			url: contextPath + '/favorites',
 			url: contextPath + '/favorites',
-				data: {
-						queryId: $queryId.val()
-				}
+			data: {
+				queryId: $queryId.val()
+			}
 		}).done(function ( data ) {
 		}).done(function ( data ) {
 			if(data.response.status === 0 
 			if(data.response.status === 0 
 				&& typeof data.response.num !== 'undefined'
 				&& typeof data.response.num !== 'undefined'
 				&& data.response.num > 0){
 				&& data.response.num > 0){
-				var urls = data.response.urls;
-				for(var i = 0; i < urls.length; i++) {
-					urls[i] = '#' + urls[i];
+				var docIds = data.response.docIds;
+				for(var i = 0; i < docIds.length; i++) {
+					docIds[i] = '#' + docIds[i];
 				}
 				}
 				$favorites.each(function(index) {
 				$favorites.each(function(index) {
 					var $favorite = $(this);
 					var $favorite = $(this);
 					var url = $favorite.attr('href');
 					var url = $favorite.attr('href');
 					var found = false;
 					var found = false;
-					for(var i = 0; i< urls.length; i++) {
-						if(url == urls[i]) {
+					for(var i = 0; i< docIds.length; i++) {
+						if(url == docIds[i]) {
 							found = true;
 							found = true;
 							break;
 							break;
 						}
 						}