View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.opensearch.log.exentity;
17  
18  import java.time.LocalDateTime;
19  import java.time.ZoneId;
20  import java.time.ZonedDateTime;
21  import java.time.format.DateTimeFormatter;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.stream.Collectors;
27  
28  import org.codelibs.core.lang.StringUtil;
29  import org.codelibs.core.misc.Pair;
30  import org.codelibs.fess.Constants;
31  import org.codelibs.fess.entity.SearchLogEvent;
32  import org.codelibs.fess.opensearch.log.bsentity.BsSearchLog;
33  import org.codelibs.fess.opensearch.log.exbhv.UserInfoBhv;
34  import org.codelibs.fess.util.ComponentUtil;
35  import org.dbflute.optional.OptionalEntity;
36  
37  /**
38   * @author FreeGen
39   */
40  public class SearchLog extends BsSearchLog implements SearchLogEvent {
41  
42      private static final long serialVersionUID = 1L;
43  
44      private final List<Pair<String, String>> searchFieldLogList = new ArrayList<>();
45  
46      private final List<Pair<String, String>> headerList = new ArrayList<>();
47  
48      private OptionalEntity<UserInfo> userInfo;
49  
50      private Map<String, Object> fields;
51  
52      private final List<Map<String, Object>> documentList = new ArrayList<>();
53  
54      @Override
55      public String getId() {
56          return asDocMeta().id();
57      }
58  
59      public void setId(final String id) {
60          asDocMeta().id(id);
61      }
62  
63      @Override
64      public Long getVersionNo() {
65          return asDocMeta().version();
66      }
67  
68      public void setVersionNo(final Long version) {
69          asDocMeta().version(version);
70      }
71  
72      public void addSearchFieldLogValue(final String name, final String value) {
73          if (StringUtil.isNotBlank(name) && StringUtil.isNotBlank(value)) {
74              searchFieldLogList.add(new Pair<>(name, value));
75          }
76      }
77  
78      public void addRequestHeaderValue(final String name, final String value) {
79          if (StringUtil.isNotBlank(name) && StringUtil.isNotBlank(value)) {
80              headerList.add(new Pair<>(name, value));
81          }
82      }
83  
84      public void addDocument(final Map<String, Object> doc) {
85          documentList.add(doc);
86      }
87  
88      public void setSearchQuery(final String query) {
89          addSearchFieldLogValue(Constants.SEARCH_FIELD_LOG_SEARCH_QUERY, query);
90      }
91  
92      public OptionalEntity<UserInfo> getUserInfo() {
93          if (getUserInfoId() == null) {
94              return OptionalEntity.empty();
95          }
96          if (userInfo == null) {
97              final UserInfoBhv userInfoBhv = ComponentUtil.getComponent(UserInfoBhv.class);
98              userInfo = userInfoBhv.selectByPK(getUserInfoId());
99          }
100         return userInfo;
101     }
102 
103     public void setUserInfo(final OptionalEntity<UserInfo> userInfo) {
104         this.userInfo = userInfo;
105         userInfo.ifPresent(e -> {
106             super.setUserInfoId(e.getId());
107         });
108     }
109 
110     public List<Pair<String, String>> getSearchFieldLogList() {
111         return searchFieldLogList;
112     }
113 
114     public List<Pair<String, String>> getRequestHeaderList() {
115         return headerList;
116     }
117 
118     public void addField(final String key, final Object value) {
119         fields.put(key, value);
120     }
121 
122     public String getLogMessage() {
123         return getSearchWord();
124     }
125 
126     @Override
127     public Map<String, Object> toSource() {
128         final Map<String, Object> sourceMap = super.toSource();
129         if (fields != null) {
130             sourceMap.putAll(fields);
131         }
132         final Map<String, List<String>> searchFieldMap = searchFieldLogList.stream()
133                 .collect(Collectors.groupingBy(Pair::getFirst, Collectors.mapping(Pair::getSecond, Collectors.toList())));
134         sourceMap.put("searchField", searchFieldMap);
135         final Map<String, List<String>> headerMap = headerList.stream()
136                 .collect(Collectors.groupingBy(Pair::getFirst, Collectors.mapping(Pair::getSecond, Collectors.toList())));
137         sourceMap.put("headers", headerMap);
138         sourceMap.put("documents", documentList);
139         return sourceMap;
140     }
141 
142     @Override
143     protected void addFieldToSource(final Map<String, Object> sourceMap, final String field, final Object value) {
144         if (value instanceof final LocalDateTime ldt) {
145             final ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());
146             super.addFieldToSource(sourceMap, field, DateTimeFormatter.ISO_INSTANT.format(zdt));
147         } else {
148             super.addFieldToSource(sourceMap, field, value);
149         }
150     }
151 
152     @Override
153     public void setUserInfoId(final String value) {
154         userInfo = null;
155         super.setUserInfoId(value);
156     }
157 
158     @Override
159     public String toString() {
160         return "SearchLog [searchFieldLogList=" + searchFieldLogList + ", headerList=" + headerList + ", userInfo=" + userInfo + ", fields="
161                 + fields + ", accessType=" + accessType + ", clientIp=" + clientIp + ", hitCount=" + hitCount + ", languages=" + languages
162                 + ", queryId=" + queryId + ", queryOffset=" + queryOffset + ", queryPageSize=" + queryPageSize + ", queryTime=" + queryTime
163                 + ", referer=" + referer + ", requestedAt=" + requestedAt + ", responseTime=" + responseTime + ", roles="
164                 + Arrays.toString(roles) + ", searchWord=" + searchWord + ", user=" + user + ", userAgent=" + userAgent + ", userInfoId="
165                 + userInfoId + ", userSessionId=" + userSessionId + ", virtualHost=" + virtualHost + ", documents=" + documentList + "]";
166     }
167 
168     @Override
169     public String getEventType() {
170         return "log";
171     }
172 }