Skip to content

Commit 2060362

Browse files
committed
1289 History of searches
1 parent bfa670a commit 2060362

File tree

18 files changed

+160
-47
lines changed

18 files changed

+160
-47
lines changed

logicaldoc-core/src/main/java/com/logicaldoc/core/searchengine/Search.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import com.logicaldoc.core.security.TenantDAO;
2828
import com.logicaldoc.core.security.user.User;
2929
import com.logicaldoc.core.security.user.UserDAO;
30+
import com.logicaldoc.core.security.user.UserEvent;
31+
import com.logicaldoc.core.security.user.UserHistory;
32+
import com.logicaldoc.core.security.user.UserHistoryDAO;
3033
import com.logicaldoc.util.Context;
3134
import com.logicaldoc.util.config.ContextProperties;
3235
import com.logicaldoc.util.plugin.PluginRegistry;
@@ -211,6 +214,18 @@ public Long mapRow(ResultSet rs, int row) throws SQLException {
211214
log.info("Search completed in {} ms and found {} hits (estimated {})", execTime, hits.size(),
212215
estimatedHitsNumber);
213216

217+
UserHistoryDAO historyDao = (UserHistoryDAO) Context.get().getBean(UserHistoryDAO.class);
218+
UserHistory transaction = options.getTransaction();
219+
if (transaction == null)
220+
transaction = new UserHistory();
221+
transaction.setUser(searchUser);
222+
transaction.setComment(StringUtils.left(options.toString(), 500));
223+
transaction.setEvent(UserEvent.SEARCH.toString());
224+
try {
225+
historyDao.store(transaction);
226+
} catch (PersistenceException e) {
227+
log.info("Error trying to save search history", e);
228+
}
214229
return hits;
215230
}
216231

logicaldoc-core/src/main/java/com/logicaldoc/core/searchengine/SearchOptions.java

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,28 @@
1010
import java.io.IOException;
1111
import java.io.ObjectInputStream;
1212
import java.io.Serializable;
13+
import java.lang.reflect.Array;
14+
import java.lang.reflect.Field;
15+
import java.lang.reflect.InvocationTargetException;
16+
import java.util.Collection;
1317
import java.util.HashSet;
1418
import java.util.Map;
1519
import java.util.Set;
1620

21+
import javax.persistence.Transient;
22+
23+
import org.apache.commons.lang3.StringUtils;
24+
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
25+
import org.apache.commons.lang3.builder.ToStringStyle;
26+
27+
import com.logicaldoc.core.security.user.UserHistory;
28+
1729
/**
1830
* Search options
1931
*
2032
* @author Michael Scholz
2133
*/
22-
public class SearchOptions implements Serializable, Comparable<SearchOptions> {
34+
public abstract class SearchOptions implements Serializable, Comparable<SearchOptions> {
2335

2436
private static final long serialVersionUID = 2L;
2537

@@ -67,6 +79,9 @@ public class SearchOptions implements Serializable, Comparable<SearchOptions> {
6779

6880
private Long tenantId = null;
6981

82+
@Transient
83+
private UserHistory transaction;
84+
7085
public Long getTemplate() {
7186
return template;
7287
}
@@ -236,6 +251,14 @@ public void setParameters(Map<String, Object> parameters) {
236251
this.parameters = parameters;
237252
}
238253

254+
public UserHistory getTransaction() {
255+
return transaction;
256+
}
257+
258+
public void setTransaction(UserHistory transaction) {
259+
this.transaction = transaction;
260+
}
261+
239262
@Override
240263
public int compareTo(SearchOptions o) {
241264
return this.getName().compareTo(o.getName());
@@ -248,9 +271,32 @@ public boolean equals(Object obj) {
248271
SearchOptions other = (SearchOptions) obj;
249272
return getName().equals(other.getName());
250273
}
251-
274+
252275
@Override
253276
public int hashCode() {
254277
return getName().hashCode();
255278
}
279+
280+
@Override
281+
public String toString() {
282+
return this.getClass().getSimpleName().replace("Options", "")
283+
+ new ReflectionToStringBuilder(this, ToStringStyle.NO_CLASS_NAME_STYLE) {
284+
protected boolean accept(Field field) {
285+
try {
286+
Object value = field.get(getObject());
287+
// avoid to print null values and empty collections
288+
return super.accept(field) && !field.getName().equals("name")
289+
&& !field.getName().equals("description") && !field.getName().equals("transaction")
290+
&& value != null && StringUtils.isNotEmpty(value.toString())
291+
&& (!field.getType().isArray() || Array.getLength(value) > 0)
292+
&& (!Collection.class.isAssignableFrom(field.getType())
293+
|| Boolean.FALSE.equals(value.getClass().getDeclaredMethod("isEmpty")
294+
.invoke(value, new Object[0])));
295+
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
296+
| NoSuchMethodException | SecurityException e) {
297+
return false;
298+
}
299+
}
300+
}.toString();
301+
}
256302
}

logicaldoc-core/src/main/java/com/logicaldoc/core/searchengine/TagSearch.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,10 @@ protected TagSearch() {
3131
@SuppressWarnings("unchecked")
3232
@Override
3333
public void internalSearch() throws SearchException {
34-
try {
35-
prepareExpression();
36-
} catch (PersistenceException e) {
37-
throw new SearchException(e);
38-
}
39-
4034
DocumentDAO dao = (DocumentDAO) Context.get().getBean(DocumentDAO.class);
4135
try {
42-
hits.addAll(dao.query(options.getExpression(), new HitMapper(), options.getMaxHits()));
36+
String query = prepareQuery();
37+
hits.addAll(dao.query(query, new HitMapper(), options.getMaxHits()));
4338
} catch (PersistenceException e) {
4439
throw new SearchException(e);
4540
}
@@ -56,7 +51,7 @@ public void internalSearch() throws SearchException {
5651
*
5752
* @throws PersistenceException error at data layer
5853
*/
59-
private void prepareExpression() throws PersistenceException {
54+
private String prepareQuery() throws PersistenceException {
6055
// Find all real documents
6156
StringBuilder query = new StringBuilder(
6257
"select A.ld_id, A.ld_customid, A.ld_docref, A.ld_type, A.ld_version, A.ld_lastmodified, ");
@@ -93,7 +88,7 @@ private void prepareExpression() throws PersistenceException {
9388

9489
log.info("executing tag search query = {}", query);
9590

96-
options.setExpression(query.toString());
91+
return query.toString();
9792
}
9893

9994
/**

logicaldoc-core/src/main/java/com/logicaldoc/core/searchengine/folder/FolderCriterion.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package com.logicaldoc.core.searchengine.folder;
22

33
import java.io.Serializable;
4+
import java.lang.reflect.Field;
45
import java.util.Date;
56
import java.util.HashMap;
67
import java.util.Map;
78

89
import org.apache.commons.lang.StringUtils;
10+
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
11+
import org.apache.commons.lang3.builder.ToStringStyle;
912

1013
import com.logicaldoc.core.metadata.Attribute;
1114

@@ -271,4 +274,19 @@ public void setDoubleValue(Double doubleValue) {
271274
public void setExtendedAttribute(boolean extendedAttribute) {
272275
this.extendedAttribute = extendedAttribute;
273276
}
277+
278+
@Override
279+
public String toString() {
280+
return new ReflectionToStringBuilder(this, ToStringStyle.NO_CLASS_NAME_STYLE) {
281+
protected boolean accept(Field field) {
282+
try {
283+
Object value = field.get(getObject());
284+
return super.accept(field) && value != null && StringUtils.isNotEmpty(value.toString())
285+
&& !field.getName().equals("field");
286+
} catch (IllegalAccessException | IllegalArgumentException | SecurityException e) {
287+
return false;
288+
}
289+
}
290+
}.toString();
291+
}
274292
}

logicaldoc-core/src/main/java/com/logicaldoc/core/searchengine/folder/FolderSearch.java

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class FolderSearch extends Search {
4949

5050
private static final String AND = " and ";
5151

52+
private String query;
53+
5254
@SuppressWarnings("unchecked")
5355
@Override
5456
public void internalSearch() throws SearchException {
@@ -63,7 +65,7 @@ public void internalSearch() throws SearchException {
6365

6466
Map<String, Object> params = null;
6567
try {
66-
params = prepareExpression();
68+
params = prepareQuery();
6769
} catch (PersistenceException e1) {
6870
throw new SearchException(e1);
6971
}
@@ -74,7 +76,7 @@ public void internalSearch() throws SearchException {
7476
// Execute the search
7577
List<Hit> folders;
7678
try {
77-
folders = dao.query(options.getExpression(), params, new HitMapper(), null);
79+
folders = dao.query(query, params, new HitMapper(), null);
7880
} catch (PersistenceException e) {
7981
throw new SearchException(e);
8082
}
@@ -104,39 +106,36 @@ public void internalSearch() throws SearchException {
104106
*
105107
* PersistenceException error at data layer
106108
*/
107-
private Map<String, Object> prepareExpression() throws PersistenceException {
108-
if (StringUtils.isNotEmpty(options.getExpression()))
109+
private Map<String, Object> prepareQuery() throws PersistenceException {
110+
if (StringUtils.isNotEmpty(query))
109111
return options.getParameters();
110112

111113
Map<String, Object> params = new HashMap<>();
112-
StringBuilder query = new StringBuilder();
114+
StringBuilder sb = new StringBuilder();
113115

114116
if (options.isRetrieveAliases())
115-
query.append("(");
117+
sb.append("(");
116118

117119
// Find all real folders
118-
query.append(
120+
sb.append(
119121
"select A.ld_id, A.ld_parentid, A.ld_name, A.ld_description, A.ld_creation, A.ld_lastmodified, A.ld_type, A.ld_foldref, C.ld_name, A.ld_templateid, A.ld_tgs, A.ld_color ");
120-
query.append(" from ld_folder A ");
121-
query.append(" left outer join ld_template C on A.ld_templateid=C.ld_id ");
122-
appendWhereClause(false, params, query);
122+
sb.append(" from ld_folder A ");
123+
sb.append(" left outer join ld_template C on A.ld_templateid=C.ld_id ");
124+
appendWhereClause(false, params, sb);
123125

124126
if (options.isRetrieveAliases()) {
125127
// Append all aliases
126-
query.append(
128+
sb.append(
127129
") UNION (select A.ld_id, A.ld_parentid, A.ld_name, A.ld_description, A.ld_creation, A.ld_lastmodified, A.ld_type, A.ld_foldref, C.ld_name, REF.ld_templateid, REF.ld_tgs, A.ld_color ");
128-
query.append(" from ld_folder A ");
129-
query.append(" join ld_folder REF on A.ld_foldref=REF.ld_id ");
130-
query.append(" left outer join ld_template C on REF.ld_templateid=C.ld_id ");
131-
appendWhereClause(true, params, query);
132-
query.append(")");
130+
sb.append(" from ld_folder A ");
131+
sb.append(" join ld_folder REF on A.ld_foldref=REF.ld_id ");
132+
sb.append(" left outer join ld_template C on REF.ld_templateid=C.ld_id ");
133+
appendWhereClause(true, params, sb);
134+
sb.append(")");
133135
}
134136

135-
options.setExpression(query.toString());
136-
137-
log.info("executing query {}", query);
138-
log.info("with parameters {}", params);
139-
137+
log.info("executing query {} with parameters {}", sb, params);
138+
query = sb.toString();
140139
return params;
141140
}
142141

logicaldoc-core/src/main/java/com/logicaldoc/core/security/user/UserEvent.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ public enum UserEvent {
2121
UPDATED("event.user.updated"),
2222
DISABLED("event.user.disabled"),
2323
ENABLED("event.user.enabled"),
24-
NEWAPIKEY("event.user.newapikey");
24+
NEWAPIKEY("event.user.newapikey"),
25+
SEARCH("event.user.search");
2526

2627
private String event;
2728

logicaldoc-core/src/main/java/com/logicaldoc/core/security/user/UserHistory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.logicaldoc.core.security.user;
22

33
import com.logicaldoc.core.History;
4+
import com.logicaldoc.core.security.Session;
45

56
/**
67
* History entry due to an event on a user.
@@ -18,6 +19,11 @@ public UserHistory() {
1819
super();
1920
}
2021

22+
public UserHistory(Session session) {
23+
super();
24+
setSession(session);
25+
}
26+
2127
public UserHistory(UserHistory source) {
2228
copyAttributesFrom(source);
2329
setAuthor(source.getAuthor());

logicaldoc-core/src/test/java/com/logicaldoc/core/searchengine/FulltextSearchTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.List;
88
import java.util.Set;
99

10+
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
1011
import org.junit.Before;
1112
import org.junit.Test;
1213
import org.slf4j.Logger;
@@ -55,6 +56,9 @@ public void testWrite() throws IOException, ClassNotFoundException {
5556
opt.write(file);
5657

5758
FulltextSearchOptions opt2 = (FulltextSearchOptions) SearchOptions.read(file);
59+
60+
System.out.println(opt);
61+
5862

5963
Assert.assertEquals("prova test", opt2.getExpression());
6064
Assert.assertEquals("it", opt2.getExpressionLanguage());

logicaldoc-core/src/test/java/com/logicaldoc/core/searchengine/TagSearchTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class TagSearchTest extends AbstractCoreTestCase {
1616

1717
@Test
1818
public void testSearch() {
19-
SearchOptions opt = new SearchOptions();
19+
SearchOptions opt = new TagSearchOptions();
2020
opt.setType(SearchOptions.TYPE_TAG);
2121
opt.setUserId(1);
2222
opt.setExpression("abc");
@@ -35,8 +35,7 @@ public void testSearch() {
3535
assertEquals(2, results.size());
3636
assertEquals(1, results.get(0).getId());
3737

38-
opt = new SearchOptions();
39-
opt.setType(SearchOptions.TYPE_TAG);
38+
opt = new TagSearchOptions();
4039
opt.setUserId(1);
4140
opt.setExpression("abc");
4241
opt.setMaxHits(1);

logicaldoc-gui/src/main/java/com/logicaldoc/gui/frontend/client/panels/HistoryPanel.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,14 @@ protected void onDraw() {
8181
list.setFields(user, event, date, comment, fileName, path);
8282
}
8383

84-
list.addDoubleClickHandler(evnt -> {
85-
LD.askForValue(I18N.message(COMMENT), I18N.message(COMMENT),
86-
list.getSelectedRecord().getAttributeAsString(COMMENT), value -> {
87-
// Nothing to do
88-
});
89-
evnt.cancel();
84+
list.addCellClickHandler(click -> {
85+
ListGridField field = list.getField(click.getColNum());
86+
String title = field.getTitle();
87+
String value = list.getDefaultFormattedFieldValue(click.getRecord(), field);
88+
LD.askForValue(title, title, value, v -> {
89+
// Nothing to do
90+
});
91+
click.cancel();
9092
});
9193

9294
ToolStrip buttons = new ToolStrip();

0 commit comments

Comments
 (0)