Skip to content

Commit 7145df7

Browse files
committed
Add SortExpressions for in-memory SCIM sorting
Converts a SortRequest into a Comparator<ScimResource> for use in stream pipelines. Documents sorting responsibility on Repository.find() -- repositories apply SortRequest if the backend supports server-side sorting; unsupported sort attributes are silently ignored per RFC 7644 S3.4.2.3. Generated-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f4b5fa1 commit 7145df7

19 files changed

Lines changed: 481 additions & 17 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: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.apache.directory.scim.spec.filter.FilterExpressions;
3737
import org.apache.directory.scim.spec.filter.FilterResponse;
3838
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;
3941
import org.apache.directory.scim.spec.resources.ScimExtension;
4042
import org.apache.directory.scim.spec.resources.ScimGroup;
4143

@@ -115,8 +117,10 @@ public void delete(String id) throws ResourceException {
115117

116118
@Override
117119
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
120+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
118121
List<ScimGroup> filtered = groups.values().stream()
119-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
122+
.filter(FilterExpressions.inMemory(filter, schema))
123+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
120124
.toList();
121125

122126
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import org.apache.directory.scim.spec.filter.FilterExpressions;
3838
import org.apache.directory.scim.spec.filter.FilterResponse;
3939
import org.apache.directory.scim.spec.filter.PageRequest;
40+
import org.apache.directory.scim.spec.filter.SortExpressions;
41+
import org.apache.directory.scim.spec.schema.Schema;
4042
import org.apache.directory.scim.spec.resources.Email;
4143
import org.apache.directory.scim.spec.resources.Name;
4244
import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -148,8 +150,10 @@ public void delete(String id) throws ResourceException {
148150

149151
@Override
150152
public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) {
153+
Schema schema = schemaRegistry.getSchema(ScimUser.SCHEMA_URI);
151154
List<ScimUser> filtered = users.values().stream()
152-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimUser.SCHEMA_URI)))
155+
.filter(FilterExpressions.inMemory(filter, schema))
156+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
153157
.toList();
154158

155159
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.apache.directory.scim.spec.filter.FilterExpressions;
3737
import org.apache.directory.scim.spec.filter.FilterResponse;
3838
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;
3941
import org.apache.directory.scim.spec.resources.ScimExtension;
4042
import org.apache.directory.scim.spec.resources.ScimGroup;
4143

@@ -115,8 +117,10 @@ public void delete(String id) throws ResourceException {
115117

116118
@Override
117119
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
120+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
118121
List<ScimGroup> filtered = groups.values().stream()
119-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
122+
.filter(FilterExpressions.inMemory(filter, schema))
123+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
120124
.toList();
121125

122126
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import org.apache.directory.scim.spec.filter.FilterExpressions;
3838
import org.apache.directory.scim.spec.filter.FilterResponse;
3939
import org.apache.directory.scim.spec.filter.PageRequest;
40+
import org.apache.directory.scim.spec.filter.SortExpressions;
41+
import org.apache.directory.scim.spec.schema.Schema;
4042
import org.apache.directory.scim.spec.resources.Email;
4143
import org.apache.directory.scim.spec.resources.Name;
4244
import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -148,8 +150,10 @@ public void delete(String id) throws ResourceException {
148150

149151
@Override
150152
public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) {
153+
Schema schema = schemaRegistry.getSchema(ScimUser.SCHEMA_URI);
151154
List<ScimUser> filtered = users.values().stream()
152-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimUser.SCHEMA_URI)))
155+
.filter(FilterExpressions.inMemory(filter, schema))
156+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
153157
.toList();
154158

155159
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.apache.directory.scim.spec.filter.FilterExpressions;
3737
import org.apache.directory.scim.spec.filter.FilterResponse;
3838
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;
3941
import org.apache.directory.scim.spec.resources.ScimExtension;
4042
import org.apache.directory.scim.spec.resources.ScimGroup;
4143

@@ -115,8 +117,10 @@ public void delete(String id) throws ResourceException {
115117

116118
@Override
117119
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
120+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
118121
List<ScimGroup> filtered = groups.values().stream()
119-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
122+
.filter(FilterExpressions.inMemory(filter, schema))
123+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
120124
.toList();
121125

122126
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import org.apache.directory.scim.spec.filter.FilterExpressions;
3838
import org.apache.directory.scim.spec.filter.FilterResponse;
3939
import org.apache.directory.scim.spec.filter.PageRequest;
40+
import org.apache.directory.scim.spec.filter.SortExpressions;
41+
import org.apache.directory.scim.spec.schema.Schema;
4042
import org.apache.directory.scim.spec.resources.Email;
4143
import org.apache.directory.scim.spec.resources.Name;
4244
import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -148,8 +150,10 @@ public void delete(String id) throws ResourceException {
148150

149151
@Override
150152
public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) {
153+
Schema schema = schemaRegistry.getSchema(ScimUser.SCHEMA_URI);
151154
List<ScimUser> filtered = users.values().stream()
152-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimUser.SCHEMA_URI)))
155+
.filter(FilterExpressions.inMemory(filter, schema))
156+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
153157
.toList();
154158

155159
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.apache.directory.scim.spec.filter.FilterExpressions;
3737
import org.apache.directory.scim.spec.filter.FilterResponse;
3838
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;
3941
import org.apache.directory.scim.spec.resources.ScimExtension;
4042
import org.apache.directory.scim.spec.resources.ScimGroup;
4143

@@ -115,8 +117,10 @@ public void delete(String id) throws ResourceException {
115117

116118
@Override
117119
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
120+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
118121
List<ScimGroup> filtered = groups.values().stream()
119-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
122+
.filter(FilterExpressions.inMemory(filter, schema))
123+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
120124
.toList();
121125

122126
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import org.apache.directory.scim.spec.filter.FilterExpressions;
3838
import org.apache.directory.scim.spec.filter.FilterResponse;
3939
import org.apache.directory.scim.spec.filter.PageRequest;
40+
import org.apache.directory.scim.spec.filter.SortExpressions;
41+
import org.apache.directory.scim.spec.schema.Schema;
4042
import org.apache.directory.scim.spec.resources.Email;
4143
import org.apache.directory.scim.spec.resources.Name;
4244
import org.apache.directory.scim.spec.resources.ScimExtension;
@@ -148,8 +150,10 @@ public void delete(String id) throws ResourceException {
148150

149151
@Override
150152
public FilterResponse<ScimUser> find(Filter filter, ScimRequestContext requestContext) {
153+
Schema schema = schemaRegistry.getSchema(ScimUser.SCHEMA_URI);
151154
List<ScimUser> filtered = users.values().stream()
152-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimUser.SCHEMA_URI)))
155+
.filter(FilterExpressions.inMemory(filter, schema))
156+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
153157
.toList();
154158

155159
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.apache.directory.scim.spec.filter.FilterExpressions;
3333
import org.apache.directory.scim.spec.filter.FilterResponse;
3434
import org.apache.directory.scim.spec.filter.PageRequest;
35+
import org.apache.directory.scim.spec.filter.SortExpressions;
36+
import org.apache.directory.scim.spec.schema.Schema;
3537
import org.apache.directory.scim.spec.resources.ScimExtension;
3638
import org.apache.directory.scim.spec.resources.ScimGroup;
3739
import org.springframework.stereotype.Service;
@@ -109,8 +111,10 @@ public void delete(String id) throws ResourceException {
109111

110112
@Override
111113
public FilterResponse<ScimGroup> find(Filter filter, ScimRequestContext requestContext) {
114+
Schema schema = schemaRegistry.getSchema(ScimGroup.SCHEMA_URI);
112115
List<ScimGroup> filtered = groups.values().stream()
113-
.filter(FilterExpressions.inMemory(filter, schemaRegistry.getSchema(ScimGroup.SCHEMA_URI)))
116+
.filter(FilterExpressions.inMemory(filter, schema))
117+
.sorted(SortExpressions.comparator(requestContext.getSortRequest(), schema))
114118
.toList();
115119

116120
PageRequest pageRequest = requestContext.getPageRequestOrDefault();

0 commit comments

Comments
 (0)