1
1
package run .halo .app .core .extension .attachment .endpoint ;
2
2
3
3
import static io .swagger .v3 .oas .annotations .media .Schema .RequiredMode .REQUIRED ;
4
- import static java .util .Comparator .comparing ;
5
4
import static org .springdoc .core .fn .builders .apiresponse .Builder .responseBuilder ;
6
5
import static org .springdoc .core .fn .builders .content .Builder .contentBuilder ;
7
6
import static org .springdoc .core .fn .builders .schema .Builder .schemaBuilder ;
8
7
import static org .springframework .boot .convert .ApplicationConversionService .getSharedInstance ;
9
8
import static org .springframework .web .reactive .function .server .RequestPredicates .contentType ;
10
9
import static run .halo .app .extension .ListResult .generateGenericClass ;
10
+ import static run .halo .app .extension .index .query .QueryFactory .all ;
11
+ import static run .halo .app .extension .index .query .QueryFactory .and ;
12
+ import static run .halo .app .extension .index .query .QueryFactory .contains ;
13
+ import static run .halo .app .extension .index .query .QueryFactory .in ;
14
+ import static run .halo .app .extension .index .query .QueryFactory .isNull ;
15
+ import static run .halo .app .extension .index .query .QueryFactory .not ;
11
16
import static run .halo .app .extension .router .QueryParamBuildUtil .buildParametersFromType ;
12
- import static run .halo .app .extension .router .selector .SelectorUtil .labelAndFieldSelectorToPredicate ;
17
+ import static run .halo .app .extension .router .selector .SelectorUtil .labelAndFieldSelectorToListOptions ;
13
18
14
19
import io .swagger .v3 .oas .annotations .media .ArraySchema ;
15
20
import io .swagger .v3 .oas .annotations .media .Schema ;
16
- import java .util .ArrayList ;
17
- import java .util .Comparator ;
18
21
import java .util .List ;
19
- import java .util .Objects ;
20
22
import java .util .Optional ;
21
- import java .util .function .Predicate ;
22
23
import lombok .extern .slf4j .Slf4j ;
24
+ import org .apache .commons .lang3 .BooleanUtils ;
23
25
import org .springdoc .core .fn .builders .requestbody .Builder ;
24
26
import org .springdoc .webflux .core .fn .SpringdocRouteBuilder ;
25
27
import org .springframework .data .domain .Sort ;
42
44
import run .halo .app .core .extension .endpoint .CustomEndpoint ;
43
45
import run .halo .app .core .extension .endpoint .SortResolver ;
44
46
import run .halo .app .core .extension .service .AttachmentService ;
45
- import run .halo .app .extension .Comparators ;
46
- import run .halo .app .extension .MetadataUtil ;
47
+ import run .halo .app .extension .ListOptions ;
48
+ import run .halo .app .extension .PageRequestImpl ;
47
49
import run .halo .app .extension .ReactiveExtensionClient ;
48
50
import run .halo .app .extension .router .IListRequest ;
49
51
import run .halo .app .extension .router .IListRequest .QueryListRequest ;
52
+ import run .halo .app .extension .router .selector .LabelSelector ;
50
53
51
54
@ Slf4j
52
55
@ Component
@@ -107,50 +110,35 @@ public RouterFunction<ServerResponse> endpoint() {
107
110
108
111
Mono <ServerResponse > search (ServerRequest request ) {
109
112
var searchRequest = new SearchRequest (request );
110
- return client .list (Group .class , group -> MetadataUtil .nullSafeLabels (group )
111
- .containsKey (Group .HIDDEN_LABEL ), null )
113
+ var groupListOptions = new ListOptions ();
114
+ groupListOptions .setLabelSelector (LabelSelector .builder ()
115
+ .exists (Group .HIDDEN_LABEL )
116
+ .build ());
117
+ return client .listAll (Group .class , groupListOptions , Sort .unsorted ())
112
118
.map (group -> group .getMetadata ().getName ())
113
119
.collectList ()
114
120
.defaultIfEmpty (List .of ())
115
- .flatMap (groups -> client .list (Attachment .class ,
116
- searchRequest .toPredicate ().and (visibleGroupPredicate (groups )),
117
- searchRequest .toComparator (),
118
- searchRequest .getPage (), searchRequest .getSize ())
119
- .flatMap (listResult -> ServerResponse .ok ()
120
- .contentType (MediaType .APPLICATION_JSON )
121
- .bodyValue (listResult )
122
- )
121
+ .flatMap (hiddenGroups -> client .listBy (Attachment .class ,
122
+ searchRequest .toListOptions (hiddenGroups ),
123
+ PageRequestImpl .of (searchRequest .getPage (), searchRequest .getSize (),
124
+ searchRequest .getSort ())
125
+ )
126
+ .flatMap (listResult -> ServerResponse .ok ()
127
+ .contentType (MediaType .APPLICATION_JSON )
128
+ .bodyValue (listResult )
129
+ )
123
130
);
124
-
125
- }
126
-
127
- static Predicate <Attachment > visibleGroupPredicate (List <String > hiddenGroups ) {
128
- return attachment -> {
129
- if (!StringUtils .hasText (attachment .getSpec ().getGroupName ())) {
130
- return true ;
131
- }
132
- return !hiddenGroups .contains (attachment .getSpec ().getGroupName ());
133
- };
134
131
}
135
132
136
133
public interface ISearchRequest extends IListRequest {
137
134
138
- @ Schema (description = "Display name of attachment" )
139
- Optional <String > getDisplayName ();
140
-
141
- @ Schema (description = "Name of policy" )
142
- Optional <String > getPolicy ();
143
-
144
- @ Schema (description = "Name of group" )
145
- Optional <String > getGroup ();
135
+ @ Schema (description = "Keyword for searching." )
136
+ Optional <String > getKeyword ();
146
137
147
138
@ Schema (description = "Filter attachments without group. This parameter will ignore group"
148
139
+ " parameter." )
149
140
Optional <Boolean > getUngrouped ();
150
141
151
- @ Schema (description = "Name of user who uploaded the attachment" )
152
- Optional <String > getUploadedBy ();
153
-
154
142
@ ArraySchema (uniqueItems = true ,
155
143
arraySchema = @ Schema (name = "sort" ,
156
144
description = "Sort property and direction of the list result. Supported fields: "
@@ -159,7 +147,6 @@ public interface ISearchRequest extends IListRequest {
159
147
implementation = String .class ,
160
148
example = "creationTimestamp,desc" ))
161
149
Sort getSort ();
162
-
163
150
}
164
151
165
152
public static class SearchRequest extends QueryListRequest implements ISearchRequest {
@@ -172,20 +159,8 @@ public SearchRequest(ServerRequest request) {
172
159
}
173
160
174
161
@ Override
175
- public Optional <String > getDisplayName () {
176
- return Optional .ofNullable (queryParams .getFirst ("displayName" ))
177
- .filter (StringUtils ::hasText );
178
- }
179
-
180
- @ Override
181
- public Optional <String > getPolicy () {
182
- return Optional .ofNullable (queryParams .getFirst ("policy" ))
183
- .filter (StringUtils ::hasText );
184
- }
185
-
186
- @ Override
187
- public Optional <String > getGroup () {
188
- return Optional .ofNullable (queryParams .getFirst ("group" ))
162
+ public Optional <String > getKeyword () {
163
+ return Optional .ofNullable (queryParams .getFirst ("keyword" ))
189
164
.filter (StringUtils ::hasText );
190
165
}
191
166
@@ -195,81 +170,35 @@ public Optional<Boolean> getUngrouped() {
195
170
.map (ungroupedStr -> getSharedInstance ().convert (ungroupedStr , Boolean .class ));
196
171
}
197
172
198
- @ Override
199
- public Optional <String > getUploadedBy () {
200
- return Optional .ofNullable (queryParams .getFirst ("uploadedBy" ))
201
- .filter (StringUtils ::hasText );
202
- }
203
-
204
173
@ Override
205
174
public Sort getSort () {
206
- return SortResolver .defaultInstance .resolve (exchange );
175
+ var sort = SortResolver .defaultInstance .resolve (exchange );
176
+ sort = sort .and (Sort .by (
177
+ Sort .Order .desc ("metadata.creationTimestamp" ),
178
+ Sort .Order .asc ("metadata.name" )
179
+ ));
180
+ return sort ;
207
181
}
208
182
209
- public Predicate <Attachment > toPredicate () {
210
- Predicate <Attachment > displayNamePred = attachment -> getDisplayName ()
211
- .map (displayNameInParam -> {
212
- String displayName = attachment .getSpec ().getDisplayName ();
213
- return displayName .contains (displayNameInParam );
214
- }).orElse (true );
215
-
216
- Predicate <Attachment > policyPred = attachment -> getPolicy ()
217
- .map (policy -> Objects .equals (policy , attachment .getSpec ().getPolicyName ()))
218
- .orElse (true );
219
-
220
- Predicate <Attachment > groupPred = attachment -> getGroup ()
221
- .map (group -> Objects .equals (group , attachment .getSpec ().getGroupName ()))
222
- .orElse (true );
223
-
224
- Predicate <Attachment > ungroupedPred = attachment -> getUngrouped ()
225
- .filter (Boolean ::booleanValue )
226
- .map (ungrouped -> !StringUtils .hasText (attachment .getSpec ().getGroupName ()))
227
- .orElseGet (() -> groupPred .test (attachment ));
183
+ public ListOptions toListOptions (List <String > hiddenGroups ) {
184
+ final var listOptions =
185
+ labelAndFieldSelectorToListOptions (getLabelSelector (), getFieldSelector ());
228
186
229
- Predicate <Attachment > uploadedByPred = attachment -> getUploadedBy ()
230
- .map (uploadedBy -> Objects .equals (uploadedBy , attachment .getSpec ().getOwnerName ()))
231
- .orElse (true );
232
-
233
-
234
- var selectorPred =
235
- labelAndFieldSelectorToPredicate (getLabelSelector (), getFieldSelector ());
236
-
237
- return displayNamePred
238
- .and (policyPred )
239
- .and (ungroupedPred )
240
- .and (uploadedByPred )
241
- .and (selectorPred );
242
- }
187
+ var fieldQuery = all ();
188
+ if (getKeyword ().isPresent ()) {
189
+ fieldQuery = and (fieldQuery , contains ("spec.displayName" , getKeyword ().get ()));
190
+ }
243
191
244
- public Comparator <Attachment > toComparator () {
245
- var sort = getSort ();
246
- List <Comparator <Attachment >> comparators = new ArrayList <>();
247
- var creationOrder = sort .getOrderFor ("creationTimestamp" );
248
- if (creationOrder != null ) {
249
- Comparator <Attachment > comparator = comparing (
250
- attachment -> attachment .getMetadata ().getCreationTimestamp ());
251
- if (creationOrder .isDescending ()) {
252
- comparator = comparator .reversed ();
253
- }
254
- comparators .add (comparator );
192
+ if (getUngrouped ().isPresent () && BooleanUtils .isTrue (getUngrouped ().get ())) {
193
+ fieldQuery = and (fieldQuery , isNull ("spec.groupName" ));
255
194
}
256
195
257
- var sizeOrder = sort .getOrderFor ("size" );
258
- if (sizeOrder != null ) {
259
- Comparator <Attachment > comparator =
260
- comparing (attachment -> attachment .getSpec ().getSize ());
261
- if (sizeOrder .isDescending ()) {
262
- comparator = comparator .reversed ();
263
- }
264
- comparators .add (comparator );
196
+ if (!hiddenGroups .isEmpty ()) {
197
+ fieldQuery = and (fieldQuery , not (in ("spec.groupName" , hiddenGroups )));
265
198
}
266
199
267
- // add default comparator
268
- comparators .add (Comparators .compareCreationTimestamp (false ));
269
- comparators .add (Comparators .compareName (true ));
270
- return comparators .stream ()
271
- .reduce (Comparator ::thenComparing )
272
- .orElse (null );
200
+ listOptions .setFieldSelector (listOptions .getFieldSelector ().andQuery (fieldQuery ));
201
+ return listOptions ;
273
202
}
274
203
}
275
204
0 commit comments