Merge branch 'release/2.15'
diff --git a/pom.xml b/pom.xml
index 070f245..71f9272 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-parent</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
<packaging>pom</packaging>
<name>SCIM - Parent</name>
<description>Penn State's Open Source JavaEE implmentation of the SCIM version 2.0 specification (RFC7642, RFC7643 and RFC7644)</description>
diff --git a/scim-client/pom.xml b/scim-client/pom.xml
index d643221..3156e13 100644
--- a/scim-client/pom.xml
+++ b/scim-client/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-parent</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-client</artifactId>
<name>SCIM - Client</name>
diff --git a/scim-common/pom.xml b/scim-common/pom.xml
index b017709..64eef9a 100644
--- a/scim-common/pom.xml
+++ b/scim-common/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-parent</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-common</artifactId>
@@ -14,12 +14,12 @@
<dependency>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-spec-protocol</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</dependency>
<dependency>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-spec-schema</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</dependency>
</dependencies>
diff --git a/scim-compliance/pom.xml b/scim-compliance/pom.xml
index 882dc53..e9f860d 100644
--- a/scim-compliance/pom.xml
+++ b/scim-compliance/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-parent</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-compliance</artifactId>
diff --git a/scim-compliance/scim-compliance-client/pom.xml b/scim-compliance/scim-compliance-client/pom.xml
index 23fc0a0..0499e8f 100644
--- a/scim-compliance/scim-compliance-client/pom.xml
+++ b/scim-compliance/scim-compliance-client/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-compliance</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-compliance-client</artifactId>
diff --git a/scim-compliance/scim-compliance-server/pom.xml b/scim-compliance/scim-compliance-server/pom.xml
index 592c846..3af381b 100644
--- a/scim-compliance/scim-compliance-server/pom.xml
+++ b/scim-compliance/scim-compliance-server/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-compliance</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-compliance-server</artifactId>
diff --git a/scim-errai/pom.xml b/scim-errai/pom.xml
index 4fc8798..a21753f 100644
--- a/scim-errai/pom.xml
+++ b/scim-errai/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-parent</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-errai</artifactId>
diff --git a/scim-server/pom.xml b/scim-server/pom.xml
index 9233849..7fe957e 100644
--- a/scim-server/pom.xml
+++ b/scim-server/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-parent</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-server</artifactId>
diff --git a/scim-server/scim-server-common/pom.xml b/scim-server/scim-server-common/pom.xml
index 01eb4a4..e9e27b6 100644
--- a/scim-server/scim-server-common/pom.xml
+++ b/scim-server/scim-server-common/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-server</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-server-common</artifactId>
diff --git a/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/PrioritySortingComparitor.java b/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/PrioritySortingComparitor.java
new file mode 100644
index 0000000..04cc674
--- /dev/null
+++ b/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/PrioritySortingComparitor.java
@@ -0,0 +1,49 @@
+package edu.psu.swe.scim.server.provider;
+
+import java.util.Comparator;
+import java.util.Set;
+
+import edu.psu.swe.scim.spec.resources.TypedAttribute;
+
+public class PrioritySortingComparitor implements Comparator<Object> {
+
+ private Set<Object> priorities;
+
+ public PrioritySortingComparitor(Set<Object> priorities) {
+ this.priorities = priorities;
+ }
+
+ @Override
+ public int compare(Object o1, Object o2) {
+ if (o1 == null) {
+ return -1;
+ }
+ if (o2 == null) {
+ return 1;
+ }
+
+ Comparable c1 = getComparableValue(o1);
+ Comparable c2 = getComparableValue(o2);
+
+ boolean o1Priority = priorities.contains(c1);
+ boolean o2Priority = priorities.contains(c2);
+
+ if (o1Priority == o2Priority) {
+ return c1.compareTo(c2);
+ } else {
+ return o1Priority ? -1 : 1;
+ }
+
+ }
+
+ public static Comparable getComparableValue(Object obj) {
+ if (obj instanceof TypedAttribute) {
+ TypedAttribute typed = (TypedAttribute) obj;
+ return typed.getType();
+ } else if (obj instanceof Comparable) {
+ return (Comparable) obj;
+ } else {
+ return obj.toString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/UpdateRequest.java b/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/UpdateRequest.java
index de80ce2..6b7a21c 100644
--- a/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/UpdateRequest.java
+++ b/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/UpdateRequest.java
@@ -5,10 +5,13 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
import javax.inject.Inject;
@@ -132,43 +135,47 @@
return patchOperations;
}
- private void sortMultiValuedCollections(Object t, AttributeContainer ac) throws IllegalArgumentException, IllegalAccessException {
- if (t != null) {
- for (Attribute attribute : ac.getAttributes()) {
- Field field = attribute.getField();
- if (attribute.isMultiValued()) {
- @SuppressWarnings("unchecked")
- List<Object> collection = (List<Object>) field.get(t);
- if (collection != null) {
- Collections.sort(collection, (o1, o2) -> {
- if (o1 == null) {
- return -1;
- }
- if (o2 == null) {
- return 1;
- }
- if (o1 instanceof TypedAttribute && o2 instanceof TypedAttribute) {
- TypedAttribute t1 = (TypedAttribute) o1;
- TypedAttribute t2 = (TypedAttribute) o2;
- String type1 = t1.getType();
- String type2 = t2.getType();
- return type1.compareTo(type2);
- }
- if (o1 instanceof Comparable<?>) {
- Comparable c1 = (Comparable)o1;
- Comparable c2 = (Comparable)o2;
- return c1.compareTo(c2);
- }
- return 0;
- });
- }
- } else if (attribute.getType() == Attribute.Type.COMPLEX) {
- sortMultiValuedCollections(field.get(t), attribute);
+ private void sortMultiValuedCollections(Object obj1, Object obj2, AttributeContainer ac) throws IllegalArgumentException, IllegalAccessException {
+ for (Attribute attribute : ac.getAttributes()) {
+ Field field = attribute.getField();
+ if (attribute.isMultiValued()) {
+ @SuppressWarnings("unchecked")
+ List<Object> collection1 = obj1 != null ? (List<Object>) field.get(obj1) : null;
+ @SuppressWarnings("unchecked")
+ List<Object> collection2 = obj2 != null ? (List<Object>) field.get(obj2) : null;
+
+ Set<Object> priorities = findCommonElements(collection1, collection2);
+ PrioritySortingComparitor prioritySortingComparitor = new PrioritySortingComparitor(priorities);
+ if (collection1 != null) {
+ Collections.sort(collection1, prioritySortingComparitor);
}
+
+ if (collection2 != null) {
+ Collections.sort(collection2, prioritySortingComparitor);
+ }
+ } else if (attribute.getType() == Attribute.Type.COMPLEX) {
+ Object nextObj1 = obj1 != null ? field.get(obj1) : null;
+ Object nextObj2 = obj2 != null ? field.get(obj2) : null;
+ sortMultiValuedCollections(nextObj1, nextObj2, attribute);
}
}
}
+ private Set<Object> findCommonElements(List<Object> list1, List<Object> list2) {
+ if (list1 == null || list2 == null) {
+ return Collections.emptySet();
+ }
+
+ Set<Object> set1 = new HashSet<>(list1);
+ Set<Object> set2 = new HashSet<>(list2);
+
+ set1 = set1.stream().map(PrioritySortingComparitor::getComparableValue).collect(Collectors.toSet());
+ set2 = set2.stream().map(PrioritySortingComparitor::getComparableValue).collect(Collectors.toSet());
+
+ set1.retainAll(set2);
+ return set1;
+ }
+
private T applyPatchOperations() {
// TODO Auto-generated method stub
return resource;
@@ -216,17 +223,18 @@
private List<PatchOperation> createPatchOperations() throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
- sortMultiValuedCollections(this.original, schema);
- Map<String, ScimExtension> extensions = this.original.getExtensions();
- for(Map.Entry<String, ScimExtension> entry : extensions.entrySet()) {
- Schema extSchema = registry.getSchema(entry.getKey());
- sortMultiValuedCollections(entry.getValue(), extSchema);
- }
- sortMultiValuedCollections(this.resource, schema);
- extensions = this.resource.getExtensions();
- for(Map.Entry<String, ScimExtension> entry : extensions.entrySet()) {
- Schema extSchema = registry.getSchema(entry.getKey());
- sortMultiValuedCollections(entry.getValue(), extSchema);
+ sortMultiValuedCollections(this.original, this.resource, schema);
+ Map<String, ScimExtension> originalExtensions = this.original.getExtensions();
+ Map<String, ScimExtension> resourceExtensions = this.resource.getExtensions();
+ Set<String> keys = new HashSet<>();
+ keys.addAll(originalExtensions.keySet());
+ keys.addAll(resourceExtensions.keySet());
+
+ for(String key: keys) {
+ Schema extSchema = registry.getSchema(key);
+ ScimExtension originalExtension = originalExtensions.get(key);
+ ScimExtension resourceExtension = resourceExtensions.get(key);
+ sortMultiValuedCollections(originalExtension, resourceExtension, extSchema);
}
//Create a Jackson ObjectMapper that reads JaxB annotations
diff --git a/scim-server/scim-server-common/src/test/java/edu/psu/swe/scim/server/provider/PrioritySortingComparitorTest.java b/scim-server/scim-server-common/src/test/java/edu/psu/swe/scim/server/provider/PrioritySortingComparitorTest.java
new file mode 100644
index 0000000..7db82f4
--- /dev/null
+++ b/scim-server/scim-server-common/src/test/java/edu/psu/swe/scim/server/provider/PrioritySortingComparitorTest.java
@@ -0,0 +1,40 @@
+package edu.psu.swe.scim.server.provider;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+public class PrioritySortingComparitorTest {
+
+ @Test
+ public void testSorting() throws Exception {
+ Set<Object> priorities = new HashSet<>();
+ priorities.add("1P");
+ priorities.add("2P");
+ PrioritySortingComparitor comparitor = new PrioritySortingComparitor(priorities);
+ List<String> list = Arrays.asList("1", "2", "1P", "2P", "3", "4");
+ Collections.sort(list, comparitor);
+ System.out.println(list);
+
+ Assertions.assertThat(list).hasSameElementsAs(Arrays.asList("1P", "2P", "1", "2", "3", "4"));
+ }
+
+ @Test
+ public void testSorting2() throws Exception {
+ Set<Object> priorities = new HashSet<>();
+ priorities.add("home");
+ priorities.add("work");
+ PrioritySortingComparitor comparitor = new PrioritySortingComparitor(priorities);
+ List<String> list = Arrays.asList("work", "local", "home");
+ Collections.sort(list, comparitor);
+ System.out.println(list);
+
+ Assertions.assertThat(list).hasSameElementsAs(Arrays.asList("home", "work", "local"));
+ }
+
+}
diff --git a/scim-server/scim-server-common/src/test/java/edu/psu/swe/scim/server/provider/UpdateRequestTest.java b/scim-server/scim-server-common/src/test/java/edu/psu/swe/scim/server/provider/UpdateRequestTest.java
index 8d61843..8b5fc58 100644
--- a/scim-server/scim-server-common/src/test/java/edu/psu/swe/scim/server/provider/UpdateRequestTest.java
+++ b/scim-server/scim-server-common/src/test/java/edu/psu/swe/scim/server/provider/UpdateRequestTest.java
@@ -1,5 +1,7 @@
package edu.psu.swe.scim.server.provider;
+import static org.junit.Assert.assertEquals;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -8,8 +10,6 @@
import javax.enterprise.inject.Instance;
-import lombok.extern.slf4j.Slf4j;
-
import org.assertj.core.api.Assertions;
import org.junit.Assert;
import org.junit.Before;
@@ -42,6 +42,7 @@
import edu.psu.swe.scim.spec.resources.PhoneNumber.GlobalPhoneNumberBuilder;
import edu.psu.swe.scim.spec.resources.Photo;
import edu.psu.swe.scim.spec.resources.ScimUser;
+import lombok.extern.slf4j.Slf4j;
@Slf4j
public class UpdateRequestTest {
@@ -336,6 +337,55 @@
}
@Test
+ public void testRemoveMultiValuedAttributeWithSorting() throws Exception {
+ UpdateRequest<ScimUser> updateRequest = new UpdateRequest<>(registry);
+
+ ScimUser user1 = createUser1();
+ ScimUser user2 = copy(user1);
+
+ Address localAddress = new Address();
+ localAddress.setStreetAddress("123 Main Street");
+ localAddress.setLocality("State College");
+ localAddress.setRegion("PA");
+ localAddress.setCountry("USA");
+ localAddress.setType("local");
+
+ user1.getAddresses().add(localAddress);
+
+ updateRequest.initWithResource("1234", user1, user2);
+ List<PatchOperation> result = updateRequest.getPatchOperations();
+
+ PatchOperation actual = assertSingleResult(result);
+
+ checkAssertions(actual, Type.REMOVE, "addresses[type EQ \"local\"]", null);
+ }
+
+ @Test
+ public void testAddMultiValuedAttributeWithSorting() throws Exception {
+ UpdateRequest<ScimUser> updateRequest = new UpdateRequest<>(registry);
+
+ ScimUser user1 = createUser1();
+ ScimUser user2 = copy(user1);
+
+ Address localAddress = new Address();
+ localAddress.setStreetAddress("123 Main Street");
+ localAddress.setLocality("State College");
+ localAddress.setRegion("PA");
+ localAddress.setCountry("USA");
+ localAddress.setType("local");
+
+ user2.getAddresses().add(localAddress);
+ user1.getAddresses().get(0).setKey("asdf");
+
+ updateRequest.initWithResource("1234", user1, user2);
+ List<PatchOperation> result = updateRequest.getPatchOperations();
+
+ assertEquals(2, result.size());
+
+ checkAssertions(result.get(1), Type.ADD, "addresses", localAddress);
+ }
+
+ @Test
public void verifyEmptyArraysDoNotCauseMove() throws Exception {
UpdateRequest<ScimUser> updateRequest = new UpdateRequest<>(registry);
diff --git a/scim-server/scim-server-example/pom.xml b/scim-server/scim-server-example/pom.xml
index b327ea9..38a987d 100644
--- a/scim-server/scim-server-example/pom.xml
+++ b/scim-server/scim-server-example/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-server</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-server-examples</artifactId>
diff --git a/scim-server/scim-server-example/scim-server-couchdb/pom.xml b/scim-server/scim-server-example/scim-server-couchdb/pom.xml
index 4e376a6..4e62664 100644
--- a/scim-server/scim-server-example/scim-server-couchdb/pom.xml
+++ b/scim-server/scim-server-example/scim-server-couchdb/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-server-examples</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-server-couchdb</artifactId>
diff --git a/scim-server/scim-server-example/scim-server-memory/pom.xml b/scim-server/scim-server-example/scim-server-memory/pom.xml
index 28da7e9..a3c1800 100644
--- a/scim-server/scim-server-example/scim-server-memory/pom.xml
+++ b/scim-server/scim-server-example/scim-server-memory/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-server-examples</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-server-memory</artifactId>
diff --git a/scim-server/scim-server-example/scim-server-rdbms/pom.xml b/scim-server/scim-server-example/scim-server-rdbms/pom.xml
index 701eeb9..b5ccd33 100644
--- a/scim-server/scim-server-example/scim-server-rdbms/pom.xml
+++ b/scim-server/scim-server-example/scim-server-rdbms/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-server-examples</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-server-rdbms</artifactId>
diff --git a/scim-spec/pom.xml b/scim-spec/pom.xml
index 3bfc170..559ab76 100644
--- a/scim-spec/pom.xml
+++ b/scim-spec/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-parent</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-spec</artifactId>
diff --git a/scim-spec/scim-spec-protocol/pom.xml b/scim-spec/scim-spec-protocol/pom.xml
index 3ee7855..f507c57 100644
--- a/scim-spec/scim-spec-protocol/pom.xml
+++ b/scim-spec/scim-spec-protocol/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-spec</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-spec-protocol</artifactId>
diff --git a/scim-spec/scim-spec-schema/pom.xml b/scim-spec/scim-spec-schema/pom.xml
index bfa5fbf..68ee275 100644
--- a/scim-spec/scim-spec-schema/pom.xml
+++ b/scim-spec/scim-spec-schema/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-spec</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-spec-schema</artifactId>
diff --git a/scim-tools/pom.xml b/scim-tools/pom.xml
index ca2b1f6..f84ad0b 100644
--- a/scim-tools/pom.xml
+++ b/scim-tools/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-parent</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-tools</artifactId>
diff --git a/scim-tools/scim-tools-cli/pom.xml b/scim-tools/scim-tools-cli/pom.xml
index ddae179..9264b2c 100644
--- a/scim-tools/scim-tools-cli/pom.xml
+++ b/scim-tools/scim-tools-cli/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-tools</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-tools-cli</artifactId>
diff --git a/scim-tools/scim-tools-common/pom.xml b/scim-tools/scim-tools-common/pom.xml
index 29dcd84..645cdbc 100644
--- a/scim-tools/scim-tools-common/pom.xml
+++ b/scim-tools/scim-tools-common/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-tools</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-tools-common</artifactId>
diff --git a/scim-tools/scim-tools-studio/pom.xml b/scim-tools/scim-tools-studio/pom.xml
index 720174b..dfcdae6 100644
--- a/scim-tools/scim-tools-studio/pom.xml
+++ b/scim-tools/scim-tools-studio/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>edu.psu.swe.scim</groupId>
<artifactId>scim-tools</artifactId>
- <version>2.14</version>
+ <version>2.15</version>
</parent>
<artifactId>scim-tools-studio</artifactId>