Skip to content

Commit 2e66105

Browse files
authored
Merge pull request #4845 from stroomworks/annotations2
Annotations2
2 parents f780bc3 + f04e2a8 commit 2e66105

File tree

18 files changed

+343
-139
lines changed

18 files changed

+343
-139
lines changed

stroom-annotation/stroom-annotation-impl-db/src/main/java/stroom/annotation/impl/db/AnnotationDaoImpl.java

+102-69
Large diffs are not rendered by default.

stroom-annotation/stroom-annotation-impl-db/src/main/java/stroom/annotation/impl/db/AnnotationFeedNameToIdCache.java

+50
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,22 @@
2121
import stroom.cache.api.CacheManager;
2222
import stroom.cache.api.StroomCache;
2323
import stroom.db.util.JooqUtil;
24+
import stroom.db.util.JooqUtil.BooleanOperator;
25+
import stroom.util.NullSafe;
2426
import stroom.util.shared.Clearable;
27+
import stroom.util.string.PatternUtil;
2528

2629
import jakarta.inject.Inject;
2730
import jakarta.inject.Provider;
2831
import jakarta.inject.Singleton;
32+
import org.jooq.Condition;
2933

34+
import java.util.ArrayList;
35+
import java.util.Collections;
36+
import java.util.HashSet;
37+
import java.util.List;
3038
import java.util.Optional;
39+
import java.util.Set;
3140

3241
import static stroom.annotation.impl.db.jooq.tables.AnnotationFeed.ANNOTATION_FEED;
3342

@@ -56,6 +65,47 @@ public Integer getOrCreateId(final String name) {
5665
return null;
5766
}
5867

68+
public List<Integer> getIds(final List<String> wildCardedTypeNames) {
69+
if (NullSafe.isEmptyCollection(wildCardedTypeNames)) {
70+
return Collections.emptyList();
71+
}
72+
return find(wildCardedTypeNames);
73+
}
74+
75+
private List<Integer> find(final List<String> wildCardedNames) {
76+
if (NullSafe.isEmptyCollection(wildCardedNames)) {
77+
return Collections.emptyList();
78+
}
79+
80+
final Set<Integer> ids = new HashSet<>(wildCardedNames.size());
81+
final List<String> namesNotInCache = new ArrayList<>(wildCardedNames.size());
82+
for (final String name : wildCardedNames) {
83+
if (!NullSafe.isBlankString(name)) {
84+
// We can't cache wildcard names as we don't know what they will match in the DB.
85+
if (PatternUtil.containsWildCards(name)) {
86+
namesNotInCache.add(name);
87+
} else {
88+
final Optional<Integer> optional = getId(name);
89+
optional.ifPresent(ids::add);
90+
}
91+
}
92+
}
93+
94+
ids.addAll(fetchWithWildCards(namesNotInCache));
95+
return ids.stream().toList();
96+
}
97+
98+
private Set<Integer> fetchWithWildCards(final List<String> wildCardedTypeNames) {
99+
final Condition condition = JooqUtil.createWildCardedStringsCondition(
100+
ANNOTATION_FEED.NAME, wildCardedTypeNames, true, BooleanOperator.OR);
101+
102+
return JooqUtil.contextResult(connectionProvider, context -> context
103+
.select(ANNOTATION_FEED.NAME, ANNOTATION_FEED.ID)
104+
.from(ANNOTATION_FEED)
105+
.where(condition)
106+
.fetchSet(ANNOTATION_FEED.ID));
107+
}
108+
59109
public Optional<Integer> getId(final String name) {
60110
if (name != null) {
61111
return cache.get(name, this::fetch);

stroom-annotation/stroom-annotation-impl-db/src/main/java/stroom/annotation/impl/db/AnnotationTagDaoImpl.java

+34
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import stroom.db.util.ExpressionMapper;
2828
import stroom.db.util.ExpressionMapperFactory;
2929
import stroom.db.util.JooqUtil;
30+
import stroom.db.util.JooqUtil.BooleanOperator;
3031
import stroom.entity.shared.ExpressionCriteria;
3132
import stroom.query.api.v2.ConditionalFormattingStyle;
3233
import stroom.util.NullSafe;
@@ -41,8 +42,10 @@
4142
import org.jooq.Condition;
4243
import org.jooq.Record;
4344

45+
import java.util.Collections;
4446
import java.util.List;
4547
import java.util.Optional;
48+
import java.util.Set;
4649
import java.util.UUID;
4750

4851
import static stroom.annotation.impl.db.jooq.tables.AnnotationTag.ANNOTATION_TAG;
@@ -209,4 +212,35 @@ public void clear() {
209212
JooqUtil.context(connectionProvider, context -> context.deleteFrom(ANNOTATION_TAG).execute());
210213
cache.clear();
211214
}
215+
216+
217+
public List<Integer> getIds(final AnnotationTagType annotationTagType,
218+
final List<String> wildCardedTypeNames) {
219+
if (NullSafe.isEmptyCollection(wildCardedTypeNames)) {
220+
return Collections.emptyList();
221+
}
222+
return find(annotationTagType, wildCardedTypeNames);
223+
}
224+
225+
private List<Integer> find(final AnnotationTagType annotationTagType,
226+
final List<String> wildCardedNames) {
227+
if (NullSafe.isEmptyCollection(wildCardedNames)) {
228+
return Collections.emptyList();
229+
}
230+
231+
return fetchWithWildCards(annotationTagType, wildCardedNames).stream().toList();
232+
}
233+
234+
private Set<Integer> fetchWithWildCards(final AnnotationTagType annotationTagType,
235+
final List<String> wildCardedTypeNames) {
236+
final Condition condition = JooqUtil.createWildCardedStringsCondition(
237+
ANNOTATION_TAG.NAME, wildCardedTypeNames, true, BooleanOperator.OR);
238+
239+
return JooqUtil.contextResult(connectionProvider, context -> context
240+
.select(ANNOTATION_TAG.NAME, ANNOTATION_TAG.ID)
241+
.from(ANNOTATION_TAG)
242+
.where(condition)
243+
.and(ANNOTATION_TAG.TYPE_ID.eq(annotationTagType.getPrimitiveValue()))
244+
.fetchSet(ANNOTATION_TAG.ID));
245+
}
212246
}

stroom-annotation/stroom-annotation-impl-db/src/test/java/stroom/annotation/impl/db/TestAnnotationDaoImpl.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import stroom.query.language.functions.Val;
2929
import stroom.query.language.functions.ValDate;
3030
import stroom.query.language.functions.ValLong;
31-
import stroom.query.language.functions.ValNull;
3231
import stroom.query.language.functions.ValString;
3332
import stroom.util.logging.LambdaLogger;
3433
import stroom.util.logging.LambdaLoggerFactory;
@@ -214,7 +213,7 @@ void testAnnotationSearch() {
214213
"1234",
215214
"Label One",
216215
"Collection One",
217-
"Comment 3",
216+
"Comment 3",
218217
"Comment 1",
219218
"Test Description",
220219
"1",

stroom-annotation/stroom-annotation-impl/src/main/java/stroom/annotation/impl/AnnotationConfig.java

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class AnnotationConfig extends AbstractConfig implements IsStroomConfig,
2525

2626
private final AnnotationDBConfig dbConfig;
2727
private final List<String> standardComments;
28+
private final String createText;
2829
private final String defaultRetentionPeriod;
2930
private final StroomDuration physicalDeleteAge;
3031
private final CacheConfig annotationTagCache;
@@ -33,6 +34,7 @@ public class AnnotationConfig extends AbstractConfig implements IsStroomConfig,
3334
public AnnotationConfig() {
3435
dbConfig = new AnnotationDBConfig();
3536
standardComments = new ArrayList<>();
37+
createText = "Create Annotation";
3638
defaultRetentionPeriod = DEFAULT_RETENTION_PERIOD;
3739
physicalDeleteAge = StroomDuration.ofDays(7);
3840
annotationTagCache = CacheConfig.builder()
@@ -49,12 +51,14 @@ public AnnotationConfig() {
4951
@JsonCreator
5052
public AnnotationConfig(@JsonProperty("db") final AnnotationDBConfig dbConfig,
5153
@JsonProperty("standardComments") final List<String> standardComments,
54+
@JsonProperty("createText") final String createText,
5255
@JsonProperty("defaultRetentionPeriod") final String defaultRetentionPeriod,
5356
@JsonProperty("physicalDeleteAge") final StroomDuration physicalDeleteAge,
5457
@JsonProperty("annotationTagCache") final CacheConfig annotationTagCache,
5558
@JsonProperty("annotationFeedCache") final CacheConfig annotationFeedCache) {
5659
this.dbConfig = dbConfig;
5760
this.standardComments = standardComments;
61+
this.createText = createText;
5862
this.defaultRetentionPeriod = defaultRetentionPeriod;
5963
this.physicalDeleteAge = physicalDeleteAge;
6064
this.annotationTagCache = annotationTagCache;
@@ -73,6 +77,12 @@ public List<String> getStandardComments() {
7377
return standardComments;
7478
}
7579

80+
@JsonProperty("createText")
81+
@JsonPropertyDescription("The text to display to create an annotation")
82+
public String getCreateText() {
83+
return createText;
84+
}
85+
7686
@JsonProperty("defaultRetentionPeriod")
7787
@JsonPropertyDescription("How long should we retain annotations by default, e.g. 5y")
7888
public String getDefaultRetentionPeriod() {

stroom-annotation/stroom-annotation-impl/src/main/java/stroom/annotation/impl/AnnotationReceiverDecoratorFactory.java

+42-10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import stroom.annotation.shared.Annotation;
2020
import stroom.annotation.shared.AnnotationDecorationFields;
21+
import stroom.annotation.shared.AnnotationTag;
2122
import stroom.annotation.shared.EventId;
2223
import stroom.expression.matcher.ExpressionMatcher;
2324
import stroom.expression.matcher.ExpressionMatcherFactory;
@@ -44,6 +45,7 @@
4445

4546
import java.util.ArrayList;
4647
import java.util.Arrays;
48+
import java.util.Collection;
4749
import java.util.HashMap;
4850
import java.util.HashSet;
4951
import java.util.List;
@@ -52,11 +54,15 @@
5254
import java.util.Objects;
5355
import java.util.Set;
5456
import java.util.function.Function;
57+
import java.util.stream.Collectors;
5558

5659
class AnnotationReceiverDecoratorFactory implements AnnotationsDecoratorFactory {
5760

5861
private static final LambdaLogger LOGGER = LambdaLoggerFactory.getLogger(AnnotationReceiverDecoratorFactory.class);
5962

63+
private static final Annotation DEFAULT_ANNOTATION = Annotation.builder().build();
64+
private static AnnotationConfig ANNOTATION_CONFIG;
65+
6066
private static final Map<String, Function<Annotation, Val>> VALUE_MAPPING = Map.ofEntries(
6167
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_ID, Annotation::getId),
6268
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_UUID, Annotation::getUuid),
@@ -66,7 +72,12 @@ class AnnotationReceiverDecoratorFactory implements AnnotationsDecoratorFactory
6672
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_UPDATED_BY, Annotation::getUpdateUser),
6773
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_TITLE, Annotation::getName),
6874
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_SUBJECT, Annotation::getSubject),
69-
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_STATUS, Annotation::getStatus),
75+
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_STATUS,
76+
AnnotationReceiverDecoratorFactory::getStatusString),
77+
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_LABEL, annotation ->
78+
getTagString(annotation.getLabels())),
79+
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_COLLECTION, annotation ->
80+
getTagString(annotation.getCollections())),
7081
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_ASSIGNED_TO, annotation ->
7182
NullSafe.get(annotation.getAssignedTo(), UserRef::toDisplayString)),
7283
nullSafeEntry(AnnotationDecorationFields.ANNOTATION_COMMENT, Annotation::getComment),
@@ -81,25 +92,52 @@ class AnnotationReceiverDecoratorFactory implements AnnotationsDecoratorFactory
8192
Map.entry(AnnotationDecorationFields.ANNOTATION_UPDATED_BY, Annotation::getUpdateUser),
8293
Map.entry(AnnotationDecorationFields.ANNOTATION_TITLE, Annotation::getName),
8394
Map.entry(AnnotationDecorationFields.ANNOTATION_SUBJECT, Annotation::getSubject),
84-
Map.entry(AnnotationDecorationFields.ANNOTATION_STATUS, Annotation::getStatus),
95+
Map.entry(AnnotationDecorationFields.ANNOTATION_STATUS,
96+
AnnotationReceiverDecoratorFactory::getStatusString),
97+
Map.entry(AnnotationDecorationFields.ANNOTATION_LABEL, annotation ->
98+
getTagString(annotation.getLabels())),
99+
Map.entry(AnnotationDecorationFields.ANNOTATION_COLLECTION, annotation ->
100+
getTagString(annotation.getCollections())),
85101
Map.entry(AnnotationDecorationFields.ANNOTATION_ASSIGNED_TO, annotation ->
86102
NullSafe.get(annotation.getAssignedTo(), UserRef::toDisplayString)),
87103
Map.entry(AnnotationDecorationFields.ANNOTATION_COMMENT, Annotation::getComment),
88104
Map.entry(AnnotationDecorationFields.ANNOTATION_HISTORY, Annotation::getHistory));
89105

90106
private final AnnotationService annotationService;
91107
private final ExpressionMatcherFactory expressionMatcherFactory;
108+
92109
private final SecurityContext securityContext;
93110

94111
@Inject
95112
AnnotationReceiverDecoratorFactory(final AnnotationService annotationService,
96113
final ExpressionMatcherFactory expressionMatcherFactory,
114+
final AnnotationConfig annotationConfig,
97115
final SecurityContext securityContext) {
98116
this.annotationService = annotationService;
99117
this.expressionMatcherFactory = expressionMatcherFactory;
118+
ANNOTATION_CONFIG = annotationConfig;
100119
this.securityContext = securityContext;
101120
}
102121

122+
private static String getTagString(final Collection<AnnotationTag> tags) {
123+
if (tags == null) {
124+
return null;
125+
}
126+
return tags.stream().map(AnnotationTag::getName).collect(Collectors.joining("|"));
127+
}
128+
129+
private static String getStatusString(final Annotation annotation) {
130+
String value = NullSafe.get(ANNOTATION_CONFIG, AnnotationConfig::getCreateText);
131+
if (annotation != null) {
132+
if (annotation.getStatus() != null) {
133+
value = annotation.getStatus().getName();
134+
} else if (annotation.getId() != null) {
135+
value = "None";
136+
}
137+
}
138+
return value;
139+
}
140+
103141
@Override
104142
public ValuesConsumer create(final ValuesConsumer valuesConsumer,
105143
final FieldIndex fieldIndex,
@@ -122,8 +160,6 @@ public ValuesConsumer create(final ValuesConsumer valuesConsumer,
122160
return valuesConsumer;
123161
}
124162

125-
final Annotation defaultAnnotation = createDefaultAnnotation();
126-
127163
return values -> {
128164
// TODO : At present we are just going to do this synchronously but in future we may do asynchronously
129165
// in which case we would increment the completion count after providing values.
@@ -148,7 +184,7 @@ public ValuesConsumer create(final ValuesConsumer valuesConsumer,
148184
}
149185

150186
if (annotations.isEmpty()) {
151-
annotations.add(defaultAnnotation);
187+
annotations.add(DEFAULT_ANNOTATION);
152188
}
153189

154190
Val[] copy = values;
@@ -174,10 +210,6 @@ public ValuesConsumer create(final ValuesConsumer valuesConsumer,
174210
};
175211
}
176212

177-
private Annotation createDefaultAnnotation() {
178-
return Annotation.builder().build();
179-
}
180-
181213
private Function<Annotation, Boolean> createFilter(final ExpressionOperator expression) {
182214
final ExpressionFilter expressionFilter = ExpressionFilter.builder()
183215
.addPrefixIncludeFilter(AnnotationDecorationFields.ANNOTATION_FIELD_PREFIX)
@@ -237,7 +269,7 @@ private void setValue(final Val[] values,
237269
} else {
238270
val = ValNull.INSTANCE;
239271
}
240-
} catch (Exception e) {
272+
} catch (final Exception e) {
241273
throw new RuntimeException(e);
242274
}
243275
values[index] = val;

0 commit comments

Comments
 (0)