Skip to content

Commit e76c5e2

Browse files
bdemersclaude
andcommitted
Add sorting and pagination helpers for in-memory SCIM repositories
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f4b5fa1 commit e76c5e2

21 files changed

Lines changed: 641 additions & 113 deletions

File tree

scim-core/src/main/java/org/apache/directory/scim/core/repository/Repository.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,14 @@ public interface Repository<T extends ScimResource> {
104104
* may be truncated by the scope specified by the passed PageRequest and
105105
* the order of the returned resources may be controlled by the passed
106106
* SortRequest.
107-
*
107+
*
108+
* <p><b>Sorting:</b> If the request context contains a {@link org.apache.directory.scim.spec.filter.SortRequest},
109+
* the repository is responsible for applying it if the backend supports server-side
110+
* sorting. The SCIM server layer does NOT apply post-retrieval sorting as a fallback.
111+
* If the requested sort attribute is not supported, the repository should silently ignore
112+
* the sort request and return results in the backend's natural order, per
113+
* <a href="https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.3">RFC 7644 §3.4.2.3</a>.</p>
114+
*
108115
* @param filter The filter that determines the ScimResources that will be
109116
* part of the ResultList.
110117
* @param requestContext the context object holding additional information about the request.

scim-server-examples/scim-server-jersey-4/src/main/java/org/apache/directory/scim/example/jersey4/service/InMemoryGroupService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
import org.apache.directory.scim.spec.filter.Filter;
3636
import org.apache.directory.scim.spec.filter.FilterExpressions;
3737
import org.apache.directory.scim.spec.filter.FilterResponse;
38-
import org.apache.directory.scim.spec.filter.PageRequest;
38+
import org.apache.directory.scim.spec.filter.SortExpressions;
39+
import org.apache.directory.scim.spec.schema.Schema;
3940
import org.apache.directory.scim.spec.resources.ScimExtension;
4041
import org.apache.directory.scim.spec.resources.ScimGroup;
4142

@@ -115,12 +116,11 @@ public void delete(String id) throws ResourceException {
115116

116117
@Override
117118
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
118-
List<ScimGroup> filtered = groups.values().stream()
119-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
120-
.toList();
121-
122-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
123-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
119+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
120+
return groups.values().stream()
121+
.filter(FilterExpressions.inMemory(filter, schema))
122+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
123+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
124124
}
125125

126126
@Override

scim-server-examples/scim-server-jersey-4/src/main/java/org/apache/directory/scim/example/jersey4/service/InMemoryUserService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
import org.apache.directory.scim.spec.filter.Filter;
3737
import org.apache.directory.scim.spec.filter.FilterExpressions;
3838
import org.apache.directory.scim.spec.filter.FilterResponse;
39-
import org.apache.directory.scim.spec.filter.PageRequest;
39+
import org.apache.directory.scim.spec.filter.SortExpressions;
40+
import org.apache.directory.scim.spec.schema.Schema;
4041
import org.apache.directory.scim.spec.resources.Email;
4142
import org.apache.directory.scim.spec.resources.Name;
4243
import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -148,12 +149,11 @@ public void delete(String id) throws ResourceException {
148149

149150
@Override
150151
public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) {
151-
List<ScimUser> filtered = users.values().stream()
152-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimUser.SCHEMA_URI)))
153-
.toList();
154-
155-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
156-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
152+
Schema schema = schemaRegistry.getSchema(ScimUser.SCHEMA_URI);
153+
return users.values().stream()
154+
.filter(FilterExpressions.inMemory(filter, schema))
155+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
156+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
157157
}
158158

159159
@Override

scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryGroupService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
import org.apache.directory.scim.spec.filter.Filter;
3636
import org.apache.directory.scim.spec.filter.FilterExpressions;
3737
import org.apache.directory.scim.spec.filter.FilterResponse;
38-
import org.apache.directory.scim.spec.filter.PageRequest;
38+
import org.apache.directory.scim.spec.filter.SortExpressions;
39+
import org.apache.directory.scim.spec.schema.Schema;
3940
import org.apache.directory.scim.spec.resources.ScimExtension;
4041
import org.apache.directory.scim.spec.resources.ScimGroup;
4142

@@ -115,12 +116,11 @@ public void delete(String id) throws ResourceException {
115116

116117
@Override
117118
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
118-
List<ScimGroup> filtered = groups.values().stream()
119-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
120-
.toList();
121-
122-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
123-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
119+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
120+
return groups.values().stream()
121+
.filter(FilterExpressions.inMemory(filter, schema))
122+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
123+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
124124
}
125125

126126
@Override

scim-server-examples/scim-server-jersey/src/main/java/org/apache/directory/scim/example/jersey/service/InMemoryUserService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
import org.apache.directory.scim.spec.filter.Filter;
3737
import org.apache.directory.scim.spec.filter.FilterExpressions;
3838
import org.apache.directory.scim.spec.filter.FilterResponse;
39-
import org.apache.directory.scim.spec.filter.PageRequest;
39+
import org.apache.directory.scim.spec.filter.SortExpressions;
40+
import org.apache.directory.scim.spec.schema.Schema;
4041
import org.apache.directory.scim.spec.resources.Email;
4142
import org.apache.directory.scim.spec.resources.Name;
4243
import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -148,12 +149,11 @@ public void delete(String id) throws ResourceException {
148149

149150
@Override
150151
public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) {
151-
List<ScimUser> filtered = users.values().stream()
152-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimUser.SCHEMA_URI)))
153-
.toList();
154-
155-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
156-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
152+
Schema schema = schemaRegistry.getSchema(ScimUser.SCHEMA_URI);
153+
return users.values().stream()
154+
.filter(FilterExpressions.inMemory(filter, schema))
155+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
156+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
157157
}
158158

159159
@Override

scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryGroupService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
import org.apache.directory.scim.spec.filter.Filter;
3636
import org.apache.directory.scim.spec.filter.FilterExpressions;
3737
import org.apache.directory.scim.spec.filter.FilterResponse;
38-
import org.apache.directory.scim.spec.filter.PageRequest;
38+
import org.apache.directory.scim.spec.filter.SortExpressions;
39+
import org.apache.directory.scim.spec.schema.Schema;
3940
import org.apache.directory.scim.spec.resources.ScimExtension;
4041
import org.apache.directory.scim.spec.resources.ScimGroup;
4142

@@ -115,12 +116,11 @@ public void delete(String id) throws ResourceException {
115116

116117
@Override
117118
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
118-
List<ScimGroup> filtered = groups.values().stream()
119-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
120-
.toList();
121-
122-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
123-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
119+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
120+
return groups.values().stream()
121+
.filter(FilterExpressions.inMemory(filter, schema))
122+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
123+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
124124
}
125125

126126
@Override

scim-server-examples/scim-server-memory/src/main/java/org/apache/directory/scim/example/memory/service/InMemoryUserService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
import org.apache.directory.scim.spec.filter.Filter;
3737
import org.apache.directory.scim.spec.filter.FilterExpressions;
3838
import org.apache.directory.scim.spec.filter.FilterResponse;
39-
import org.apache.directory.scim.spec.filter.PageRequest;
39+
import org.apache.directory.scim.spec.filter.SortExpressions;
40+
import org.apache.directory.scim.spec.schema.Schema;
4041
import org.apache.directory.scim.spec.resources.Email;
4142
import org.apache.directory.scim.spec.resources.Name;
4243
import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -148,12 +149,11 @@ public void delete(String id) throws ResourceException {
148149

149150
@Override
150151
public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) {
151-
List<ScimUser> filtered = users.values().stream()
152-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimUser.SCHEMA_URI)))
153-
.toList();
154-
155-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
156-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
152+
Schema schema = schemaRegistry.getSchema(ScimUser.SCHEMA_URI);
153+
return users.values().stream()
154+
.filter(FilterExpressions.inMemory(filter, schema))
155+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
156+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
157157
}
158158

159159
@Override

scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryGroupService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
import org.apache.directory.scim.spec.filter.Filter;
3636
import org.apache.directory.scim.spec.filter.FilterExpressions;
3737
import org.apache.directory.scim.spec.filter.FilterResponse;
38-
import org.apache.directory.scim.spec.filter.PageRequest;
38+
import org.apache.directory.scim.spec.filter.SortExpressions;
39+
import org.apache.directory.scim.spec.schema.Schema;
3940
import org.apache.directory.scim.spec.resources.ScimExtension;
4041
import org.apache.directory.scim.spec.resources.ScimGroup;
4142

@@ -115,12 +116,11 @@ public void delete(String id) throws ResourceException {
115116

116117
@Override
117118
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
118-
List<ScimGroup> filtered = groups.values().stream()
119-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
120-
.toList();
121-
122-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
123-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
119+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
120+
return groups.values().stream()
121+
.filter(FilterExpressions.inMemory(filter, schema))
122+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
123+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
124124
}
125125

126126
@Override

scim-server-examples/scim-server-quarkus/src/main/java/org/apache/directory/scim/example/quarkus/service/InMemoryUserService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
import org.apache.directory.scim.spec.filter.Filter;
3737
import org.apache.directory.scim.spec.filter.FilterExpressions;
3838
import org.apache.directory.scim.spec.filter.FilterResponse;
39-
import org.apache.directory.scim.spec.filter.PageRequest;
39+
import org.apache.directory.scim.spec.filter.SortExpressions;
40+
import org.apache.directory.scim.spec.schema.Schema;
4041
import org.apache.directory.scim.spec.resources.Email;
4142
import org.apache.directory.scim.spec.resources.Name;
4243
import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -148,12 +149,11 @@ public void delete(String id) throws ResourceException {
148149

149150
@Override
150151
public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) {
151-
List<ScimUser> filtered = users.values().stream()
152-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimUser.SCHEMA_URI)))
153-
.toList();
154-
155-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
156-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
152+
Schema schema = schemaRegistry.getSchema(ScimUser.SCHEMA_URI);
153+
return users.values().stream()
154+
.filter(FilterExpressions.inMemory(filter, schema))
155+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
156+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
157157
}
158158

159159
@Override

scim-server-examples/scim-server-spring-boot-4/src/main/java/org/apache/directory/scim/example/spring/service/InMemoryGroupService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
import org.apache.directory.scim.spec.filter.Filter;
3232
import org.apache.directory.scim.spec.filter.FilterExpressions;
3333
import org.apache.directory.scim.spec.filter.FilterResponse;
34-
import org.apache.directory.scim.spec.filter.PageRequest;
34+
import org.apache.directory.scim.spec.filter.SortExpressions;
35+
import org.apache.directory.scim.spec.schema.Schema;
3536
import org.apache.directory.scim.spec.resources.ScimExtension;
3637
import org.apache.directory.scim.spec.resources.ScimGroup;
3738
import org.springframework.stereotype.Service;
@@ -109,12 +110,11 @@ public void delete(String id) throws ResourceException {
109110

110111
@Override
111112
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
112-
List<ScimGroup> filtered = groups.values().stream()
113-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
114-
.toList();
115-
116-
PageRequest pageRequest = requestContext.getPageRequestOrDefault();
117-
return new FilterResponse<>(pageRequest.paginate(filtered), filtered.size());
113+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
114+
return groups.values().stream()
115+
.filter(FilterExpressions.inMemory(filter, schema))
116+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
117+
.collect(FilterResponse.paginate(requestContext.getPageRequestOrDefault()));
118118
}
119119

120120
@Override

0 commit comments

Comments
 (0)