11package org .cbioportal .domain .generic_assay .usecase ;
22
3+ import java .util .Collection ;
34import java .util .Collections ;
45import java .util .HashSet ;
56import java .util .LinkedHashSet ;
67import java .util .List ;
8+ import java .util .Locale ;
79import java .util .Set ;
810import org .cbioportal .domain .generic_assay .repository .GenericAssayRepository ;
911import org .cbioportal .legacy .model .meta .GenericAssayMeta ;
@@ -43,6 +45,27 @@ public GetGenericAssayMetaUseCase(GenericAssayRepository repository) {
4345 + " #projection}" )
4446 public List <GenericAssayMeta > execute (
4547 List <String > stableIds , List <String > molecularProfileIds , String projection ) {
48+ return execute (stableIds , molecularProfileIds , projection , null , null , null );
49+ }
50+
51+ @ Cacheable (
52+ cacheResolver = "generalRepositoryCacheResolver" ,
53+ condition = "@cacheEnabledConfig.getEnabled()" ,
54+ key =
55+ "{#stableIds == null ? null : new java.util.TreeSet(#stableIds.?[#this != null]),"
56+ + " #molecularProfileIds == null ? null : new java.util.TreeSet(#molecularProfileIds.?[#this != null]),"
57+ + " #projection,"
58+ + " (#searchTerm == null or #searchTerm.trim().isEmpty() ? null : #searchTerm.trim()),"
59+ + " #pageSize, #pageNumber}" )
60+ public List <GenericAssayMeta > execute (
61+ List <String > stableIds ,
62+ List <String > molecularProfileIds ,
63+ String projection ,
64+ String searchTerm ,
65+ Integer pageSize ,
66+ Integer pageNumber ) {
67+ String normalizedSearchTerm = normalizeSearchTerm (searchTerm );
68+ Integer offset = pageSize == null || pageNumber == null ? null : pageSize * pageNumber ;
4669
4770 if (molecularProfileIds != null ) {
4871 List <String > sortedProfileIds = molecularProfileIds .stream ().distinct ().sorted ().toList ();
@@ -52,16 +75,16 @@ public List<GenericAssayMeta> execute(
5275
5376 if ("ID" .equals (projection )) {
5477 // Lightweight path: resolve IDs only, skip meta fetch
55- Set <String > resolvedIds =
56- new LinkedHashSet <>(repository .getGenericAssayStableIdsByProfileIds (sortedProfileIds ));
57- if (stableIds != null ) {
58- resolvedIds .retainAll (new HashSet <>(stableIds ));
59- }
60- return resolvedIds .stream ().map (GenericAssayMeta ::new ).toList ();
78+ var filteredIds =
79+ resolveFilteredIdsByProfileIds (sortedProfileIds , stableIds , normalizedSearchTerm );
80+ return pageIds (filteredIds , pageSize , pageNumber ).stream ()
81+ .map (GenericAssayMeta ::new )
82+ .toList ();
6183 }
6284
6385 // Single merged query: profile → entity + meta join
64- return repository .getGenericAssayMetaByProfileIds (sortedProfileIds , stableIds );
86+ return repository .getGenericAssayMetaByProfileIds (
87+ sortedProfileIds , stableIds , normalizedSearchTerm , pageSize , offset );
6588 }
6689
6790 if (stableIds == null || stableIds .isEmpty ()) {
@@ -71,9 +94,96 @@ public List<GenericAssayMeta> execute(
7194 List <String > distinctStableIds = stableIds .stream ().distinct ().toList ();
7295
7396 if ("ID" .equals (projection )) {
74- return distinctStableIds .stream ().map (GenericAssayMeta ::new ).toList ();
97+ return pageIds (
98+ filterIdsBySearchTerm (distinctStableIds , normalizedSearchTerm ), pageSize , pageNumber )
99+ .stream ()
100+ .map (GenericAssayMeta ::new )
101+ .toList ();
102+ }
103+
104+ return repository .getGenericAssayMetaByStableIds (
105+ distinctStableIds , normalizedSearchTerm , pageSize , offset );
106+ }
107+
108+ // Mirrors the ID-projection branches in execute(): count must use the same match
109+ // criteria (stable ID only, no name/description) as the data it's counting, or the
110+ // reported total-count won't line up with what's actually paginable for that projection.
111+ @ Cacheable (
112+ cacheResolver = "generalRepositoryCacheResolver" ,
113+ condition = "@cacheEnabledConfig.getEnabled()" ,
114+ key =
115+ "{#stableIds == null ? null : new java.util.TreeSet(#stableIds.?[#this != null]),"
116+ + " #molecularProfileIds == null ? null : new java.util.TreeSet(#molecularProfileIds.?[#this != null]),"
117+ + " #projection,"
118+ + " (#searchTerm == null or #searchTerm.trim().isEmpty() ? null : #searchTerm.trim()),"
119+ + " 'count'}" )
120+ public Integer count (
121+ List <String > stableIds ,
122+ List <String > molecularProfileIds ,
123+ String projection ,
124+ String searchTerm ) {
125+ String normalizedSearchTerm = normalizeSearchTerm (searchTerm );
126+
127+ if (molecularProfileIds != null ) {
128+ List <String > sortedProfileIds = molecularProfileIds .stream ().distinct ().sorted ().toList ();
129+ if (sortedProfileIds .isEmpty ()) {
130+ return 0 ;
131+ }
132+ if ("ID" .equals (projection )) {
133+ return resolveFilteredIdsByProfileIds (sortedProfileIds , stableIds , normalizedSearchTerm )
134+ .size ();
135+ }
136+ return repository .countGenericAssayMetaByProfileIds (
137+ sortedProfileIds , stableIds , normalizedSearchTerm );
138+ }
139+
140+ if (stableIds == null || stableIds .isEmpty ()) {
141+ return 0 ;
142+ }
143+
144+ List <String > distinctStableIds = stableIds .stream ().distinct ().toList ();
145+ if ("ID" .equals (projection )) {
146+ return filterIdsBySearchTerm (distinctStableIds , normalizedSearchTerm ).size ();
147+ }
148+
149+ return repository .countGenericAssayMetaByStableIds (distinctStableIds , normalizedSearchTerm );
150+ }
151+
152+ private String normalizeSearchTerm (String searchTerm ) {
153+ if (searchTerm == null || searchTerm .isBlank ()) {
154+ return null ;
155+ }
156+ return searchTerm .trim ();
157+ }
158+
159+ private boolean containsSearchText (String value , String searchTerm ) {
160+ return searchTerm == null
161+ || (value != null
162+ && value .toLowerCase (Locale .ROOT ).contains (searchTerm .toLowerCase (Locale .ROOT )));
163+ }
164+
165+ private List <String > filterIdsBySearchTerm (Collection <String > ids , String normalizedSearchTerm ) {
166+ return ids .stream ().filter (id -> containsSearchText (id , normalizedSearchTerm )).toList ();
167+ }
168+
169+ private List <String > resolveFilteredIdsByProfileIds (
170+ List <String > sortedProfileIds , List <String > stableIds , String normalizedSearchTerm ) {
171+ Set <String > resolvedIds =
172+ new LinkedHashSet <>(repository .getGenericAssayStableIdsByProfileIds (sortedProfileIds ));
173+ if (stableIds != null ) {
174+ resolvedIds .retainAll (new HashSet <>(stableIds ));
75175 }
176+ return filterIdsBySearchTerm (resolvedIds , normalizedSearchTerm );
177+ }
76178
77- return repository .getGenericAssayMetaByStableIds (distinctStableIds );
179+ private List <String > pageIds (List <String > ids , Integer pageSize , Integer pageNumber ) {
180+ if (pageSize == null || pageNumber == null ) {
181+ return ids ;
182+ }
183+ int offset = pageSize * pageNumber ;
184+ if (offset >= ids .size ()) {
185+ return Collections .emptyList ();
186+ }
187+ return ids .subList (offset , Math .min (offset + pageSize , ids .size ()));
78188 }
79189}
0 commit comments