Merge pull request #108 from apache/dependabot/maven/org.mockito-mockito-core-4.7.0

Bump mockito-core from 4.6.1 to 4.7.0
diff --git a/lombok.config b/lombok.config
index 8571a69..7e0eb60 100644
--- a/lombok.config
+++ b/lombok.config
@@ -1 +1,2 @@
 lombok.accessors.chain=true
+lombok.addLombokGeneratedAnnotation = true
diff --git a/pom.xml b/pom.xml
index af4b379..e3a675f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -231,7 +231,7 @@
       <dependency>
         <groupId>org.mockito</groupId>
         <artifactId>mockito-junit-jupiter</artifactId>
-        <version>4.6.1</version>
+        <version>4.7.0</version>
         <scope>test</scope>
       </dependency>
       <dependency>
@@ -392,7 +392,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-javadoc-plugin</artifactId>
-          <version>3.4.0</version>
+          <version>3.4.1</version>
           <executions>
             <execution>
               <id>attach-javadocs</id>
diff --git a/scim-server-examples/scim-server-jersey/pom.xml b/scim-server-examples/scim-server-jersey/pom.xml
index f7ff32d..c8b05ff 100644
--- a/scim-server-examples/scim-server-jersey/pom.xml
+++ b/scim-server-examples/scim-server-jersey/pom.xml
@@ -28,7 +28,7 @@
   <name>SCIM - Server - Examples - Jersey</name>
 
   <properties>
-    <jersey.version>3.0.5</jersey.version>
+    <jersey.version>3.0.6</jersey.version>
   </properties>
 
   <dependencyManagement>
diff --git a/scim-server/pom.xml b/scim-server/pom.xml
index fa99682..8dbd477 100644
--- a/scim-server/pom.xml
+++ b/scim-server/pom.xml
@@ -50,6 +50,10 @@
       <artifactId>scim-spec-protocol</artifactId>
     </dependency>
     <dependency>
+      <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
+      <artifactId>jackson-jakarta-rs-json-provider</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <scope>provided</scope>
diff --git a/scim-server/src/main/java/org/apache/directory/scim/server/provider/Provider.java b/scim-server/src/main/java/org/apache/directory/scim/server/provider/Provider.java
index ec4d50a..a6ab223 100644
--- a/scim-server/src/main/java/org/apache/directory/scim/server/provider/Provider.java
+++ b/scim-server/src/main/java/org/apache/directory/scim/server/provider/Provider.java
@@ -69,7 +69,7 @@
    * Allows the SCIM server's REST implementation to update and existing
    * resource via a PUT to a valid end-point.
    * 
-   * @param resource The ScimResource to update and persist.
+   * @param updateRequest The ScimResource to update and persist.
    * @return The newly updated ScimResource.
    * @throws UnableToUpdateResourceException When the ScimResource cannot be
    *         updated.
diff --git a/scim-server/src/main/java/org/apache/directory/scim/server/rest/ScimJacksonXmlBindJsonProvider.java b/scim-server/src/main/java/org/apache/directory/scim/server/rest/ScimJacksonXmlBindJsonProvider.java
index 6844070..5cc844c 100644
--- a/scim-server/src/main/java/org/apache/directory/scim/server/rest/ScimJacksonXmlBindJsonProvider.java
+++ b/scim-server/src/main/java/org/apache/directory/scim/server/rest/ScimJacksonXmlBindJsonProvider.java
@@ -19,8 +19,8 @@
 
 package org.apache.directory.scim.server.rest;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.jakarta.rs.json.JacksonXmlBindJsonProvider;
+import org.apache.directory.scim.spec.json.ObjectMapperFactory;
 import org.apache.directory.scim.spec.protocol.Constants;
 
 import jakarta.inject.Inject;
@@ -37,7 +37,7 @@
 public class ScimJacksonXmlBindJsonProvider extends JacksonXmlBindJsonProvider {
 
   @Inject
-  public ScimJacksonXmlBindJsonProvider(ObjectMapper objectMapper) {
-    super(objectMapper, DEFAULT_ANNOTATIONS);
+  public ScimJacksonXmlBindJsonProvider() {
+    super(ObjectMapperFactory.getObjectMapper(), DEFAULT_ANNOTATIONS);
   }
 }
diff --git a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/CompareOperator.java b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/CompareOperator.java
index 59150c6..47cccea 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/CompareOperator.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/CompareOperator.java
@@ -21,14 +21,14 @@
 
 public enum CompareOperator {
   
-  EQ,
-  NE,
-  CO,
-  SW,
-  EW,
-  GT,
-  GE,
-  LT,
-  LE;
-  
+  EQ, // equal
+  NE, // not equal
+  CO, // contains
+  SW, // starts with
+  EW, // ends with
+  PR, // present (has value)
+  GT, // greater than
+  GE, // greater than or equal
+  LT, // greater than
+  LE; // greater than or equal
 }
diff --git a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterBuilder.java b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterBuilder.java
index 6fe338f..5303aa7 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterBuilder.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterBuilder.java
@@ -5,6 +5,7 @@
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.Date;
+import java.util.function.UnaryOperator;
 
 public interface FilterBuilder {
 
@@ -12,6 +13,10 @@
 
   FilterBuilder and(FilterExpression fe1);
 
+  default FilterBuilder and(UnaryOperator<FilterBuilder> filter) {
+    return and(filter.apply(FilterBuilder.create()).build());
+  }
+
   default FilterBuilder and(Filter filter) {
     return and(filter.getExpression());
   }
@@ -22,6 +27,10 @@
     return and(left.getExpression(), right.getExpression());
   }
 
+  default FilterBuilder and(UnaryOperator<FilterBuilder> left, UnaryOperator<FilterBuilder> right) {
+    return and(left.apply(FilterBuilder.create()).build(), right.apply(FilterBuilder.create()).build());
+  }
+
   FilterBuilder or();
 
   FilterBuilder or(FilterExpression fe1);
@@ -30,11 +39,18 @@
     return or(filter.getExpression());
   }
 
+  default FilterBuilder or(UnaryOperator<FilterBuilder> filter) {
+    return or(filter.apply(FilterBuilder.create()).build());
+  }
+
   FilterBuilder or(FilterExpression left, FilterExpression right);
 
   default FilterBuilder or(Filter left, Filter right) {
     return or(left.getExpression(), right.getExpression());
   }
+  default FilterBuilder or(UnaryOperator<FilterBuilder> left, UnaryOperator<FilterBuilder> right) {
+    return or(left.apply(FilterBuilder.create()).build(), right.apply(FilterBuilder.create()).build());
+  }
 
   FilterBuilder equalTo(String key, String value);
 
@@ -102,15 +118,25 @@
 
   FilterBuilder contains(String key, String value);
 
+  FilterBuilder present(String key);
+
   FilterBuilder not(FilterExpression fe);
 
   default FilterBuilder not(Filter filter) {
     return not(filter.getExpression());
   }
 
-  FilterBuilder attributeHas(String attribute, FilterExpression filter) throws FilterParseException;
+  default FilterBuilder not(UnaryOperator<FilterBuilder> filter) {
+    return not(filter.apply(FilterBuilder.create()).build());
+  }
 
-  default FilterBuilder attributeHas(String attribute, Filter filter) throws FilterParseException {
+  FilterBuilder attributeHas(String attribute, FilterExpression filter);
+
+  default FilterBuilder attributeHas(String attribute, UnaryOperator<FilterBuilder> filter) {
+    return attributeHas(attribute, filter.apply(FilterBuilder.create()).build());
+  }
+
+  default FilterBuilder attributeHas(String attribute, Filter filter) {
     return attributeHas(attribute, filter.getExpression());
   }
 
diff --git a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterComparisonFilterBuilder.java b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterComparisonFilterBuilder.java
index 39484cb..ad83323 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterComparisonFilterBuilder.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterComparisonFilterBuilder.java
@@ -182,6 +182,16 @@
     }
 
     @Override
+    public FilterBuilder present(String key) {
+      AttributeReference ar = new AttributeReference(key);
+      FilterExpression filterExpression = new AttributePresentExpression(ar);
+
+      handleComparisonExpression(filterExpression);
+
+      return this;
+    }
+
+    @Override
     public <T extends Number> FilterBuilder greaterThan(String key, T value) {
       AttributeReference ar = new AttributeReference(key);
       FilterExpression filterExpression = new AttributeComparisonExpression(ar, CompareOperator.GT, value);
@@ -354,7 +364,7 @@
     }
 
     @Override
-    public FilterBuilder attributeHas(String attribute, FilterExpression expression) throws FilterParseException {
+    public FilterBuilder attributeHas(String attribute, FilterExpression expression) {
       handleComparisonExpression(ValuePathExpression.fromFilterExpression(attribute, expression));
 
       return this;
diff --git a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterExpression.java b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterExpression.java
index 42a837c..0e95ae6 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterExpression.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/FilterExpression.java
@@ -21,7 +21,7 @@
 
 public interface FilterExpression {
   
-  public String toFilter();
+  String toFilter();
 
   void setAttributePath(String urn, String parentAttributeName);
 
diff --git a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/ValuePathExpression.java b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/ValuePathExpression.java
index cfd666e..ac44f24 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/ValuePathExpression.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/org/apache/directory/scim/spec/protocol/filter/ValuePathExpression.java
@@ -37,13 +37,13 @@
     this.attributePath = attributePath;
   }
 
-  public static ValuePathExpression fromFilterExpression(AttributeReference attrRef, FilterExpression attributeExpression) throws FilterParseException {
+  public static ValuePathExpression fromFilterExpression(AttributeReference attrRef, FilterExpression attributeExpression) {
     ValuePathExpression vpe = new ValuePathExpression(attrRef, attributeExpression);
 
     return vpe;
   }
 
-  public static ValuePathExpression fromFilterExpression(String attribute, FilterExpression expression) throws FilterParseException {
+  public static ValuePathExpression fromFilterExpression(String attribute, FilterExpression expression) {
     AttributeReference attributeReference = new AttributeReference(attribute);
 
     return fromFilterExpression(attributeReference,  expression);
diff --git a/scim-spec/scim-spec-protocol/src/test/java/org/apache/directory/scim/spec/protocol/filter/FilterBuilderPresentTest.java b/scim-spec/scim-spec-protocol/src/test/java/org/apache/directory/scim/spec/protocol/filter/FilterBuilderPresentTest.java
new file mode 100644
index 0000000..5e47864
--- /dev/null
+++ b/scim-spec/scim-spec-protocol/src/test/java/org/apache/directory/scim/spec/protocol/filter/FilterBuilderPresentTest.java
@@ -0,0 +1,48 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+ 
+* http://www.apache.org/licenses/LICENSE-2.0
+
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.directory.scim.spec.protocol.filter;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.directory.scim.spec.protocol.search.Filter;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Slf4j
+public class FilterBuilderPresentTest {
+
+  @Test
+  public void testAttributePresent() throws FilterParseException {
+    Filter filter = FilterBuilder.create().present("address.streetAddress").build();
+    Filter expected = new Filter("address.streetAddress PR");
+    assertThat(filter).isEqualTo(expected);
+  }
+
+  @Test
+  public void testStartsWith()  throws FilterParseException {
+    Filter filter = FilterBuilder.create()
+      .present("address.streetAddress")
+      .and()
+      .equalTo("address.region", "CA")
+      .build();
+    Filter expected = new Filter("address.streetAddress PR AND address.region EQ \"CA\"");
+    assertThat(filter).isEqualTo(expected);
+  }
+}
diff --git a/scim-spec/scim-spec-schema/pom.xml b/scim-spec/scim-spec-schema/pom.xml
index a87cb2c..2b5c799 100644
--- a/scim-spec/scim-spec-schema/pom.xml
+++ b/scim-spec/scim-spec-schema/pom.xml
@@ -32,10 +32,6 @@
       <groupId>jakarta.xml.bind</groupId>
       <artifactId>jakarta.xml.bind-api</artifactId>
 		</dependency>
-		<dependency>
-      <groupId>jakarta.ws.rs</groupId>
-      <artifactId>jakarta.ws.rs-api</artifactId>
-    </dependency>
     <dependency>
       <groupId>jakarta.validation</groupId>
       <artifactId>jakarta.validation-api</artifactId>
@@ -52,10 +48,6 @@
       <scope>test</scope>
     </dependency>
   <dependency>
-    <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
-    <artifactId>jackson-jakarta-rs-json-provider</artifactId>
-  </dependency>
-  <dependency>
     <groupId>org.hibernate.validator</groupId>
     <artifactId>hibernate-validator</artifactId>
     <scope>test</scope>
@@ -74,6 +66,14 @@
 		<groupId>org.slf4j</groupId>
 		<artifactId>slf4j-api</artifactId>
 	</dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.module</groupId>
+      <artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId>
+    </dependency>
 	<dependency>
 		<!-- TODO Remove this dependency -->
 		<groupId>com.fasterxml.jackson.core</groupId>
diff --git a/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/resources/ScimResource.java b/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/resources/ScimResource.java
index a9badf1..596a244 100644
--- a/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/resources/ScimResource.java
+++ b/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/resources/ScimResource.java
@@ -26,6 +26,7 @@
 import lombok.EqualsAndHashCode;
 import org.apache.directory.scim.spec.annotation.ScimAttribute;
 import org.apache.directory.scim.spec.annotation.ScimExtensionType;
+import org.apache.directory.scim.spec.annotation.ScimResourceType;
 import org.apache.directory.scim.spec.exception.InvalidExtensionException;
 import org.apache.directory.scim.spec.extension.ScimExtensionRegistry;
 import org.apache.directory.scim.spec.json.ObjectMapperFactory;
@@ -83,6 +84,11 @@
   public ScimResource(String urn) {
     super(urn);
     this.baseUrn = urn;
+
+    ScimResourceType resourceTypeAnnotation = getClass().getAnnotation(ScimResourceType.class);
+    if (resourceTypeAnnotation != null) {
+      this.meta = new Meta().setResourceType(resourceTypeAnnotation.id());
+    }
   }
 
   /**
diff --git a/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/schema/Meta.java b/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/schema/Meta.java
index fe634f7..ed68808 100644
--- a/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/schema/Meta.java
+++ b/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/schema/Meta.java
@@ -31,6 +31,7 @@
 
 import org.apache.directory.scim.spec.adapter.LocalDateTimeAdapter;
 import lombok.Data;
+import org.apache.directory.scim.spec.annotation.ScimAttribute;
 
 /**
  * Defines the structure of the meta attribute for all SCIM resources as defined
@@ -49,20 +50,25 @@
 
   @XmlElement
   @Size(min = 1)
+  @ScimAttribute(description = "The name of the resource type of the resource.")
   String resourceType;
   
   @XmlElement
   @XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
+  @ScimAttribute(description = "The DateTime that the resource was added to the service provider.")
   LocalDateTime created;
   
   @XmlElement
   @XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
+  @ScimAttribute(description = "The most recent DateTime that the details of this resource were updated at the service provider.")
   LocalDateTime lastModified;
   
   @XmlElement
+  @ScimAttribute(description = "The URI of the resource being returned.")
   String location;
   
   @XmlElement
+  @ScimAttribute(description = "The version of the resource being returned.  This value must be the same as the entity-tag (ETag) HTTP response header")
   String version;
 
 }
diff --git a/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/schema/ServiceProviderConfiguration.java b/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/schema/ServiceProviderConfiguration.java
index e73307b..e9fc7eb 100644
--- a/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/schema/ServiceProviderConfiguration.java
+++ b/scim-spec/scim-spec-schema/src/main/java/org/apache/directory/scim/spec/schema/ServiceProviderConfiguration.java
@@ -47,12 +47,48 @@
   public static class AuthenticationSchema {
 
     public enum Type {
-      @XmlEnumValue("oauth")
-      OAUTH, @XmlEnumValue("oauth2")
-      OAUTH2, @XmlEnumValue("oauthbearertoken")
-      OAUTH_BEARER, @XmlEnumValue("httpbasic")
-      HTTP_BASIC, @XmlEnumValue("httpdigest")
-      HTTP_DIGEST;
+      @XmlEnumValue("oauth") OAUTH(
+        "oauth",
+        "OAuth 1.0",
+        "Authentication scheme using the OAuth 1.0 Standard",
+        "https://www.rfc-editor.org/rfc/rfc5849.html"),
+      @XmlEnumValue("oauth2") OAUTH2(
+        "oauth2",
+        "OAuth 2.0",
+        "Authentication scheme using the OAuth 2.0 Standard",
+        "https://www.rfc-editor.org/rfc/rfc6749.html"),
+      @XmlEnumValue("oauthbearertoken") OAUTH_BEARER(
+        "oauthbearertoken",
+        "OAuth Bearer Token",
+        "Authentication scheme using the OAuth Bearer Token Standard",
+        "http://www.rfc-editor.org/info/rfc6750"),
+      @XmlEnumValue("httpbasic") HTTP_BASIC(
+        "httpbasic",
+        "HTTP Basic",
+        "Authentication scheme using the HTTP Basic Standard",
+        "http://www.rfc-editor.org/info/rfc2617"),
+      @XmlEnumValue("httpdigest") HTTP_DIGEST(
+        "httpdigest",
+        "HTTP Digest",
+        "Authentication scheme using the HTTP Digest Standard",
+        "https://www.rfc-editor.org/rfc/rfc7616.html");
+
+      private final String type;
+      private final String specUri;
+      private final String defaultName;
+      private final String defaultDescription;
+
+      Type(String type, String defaultName, String defaultDescription, String specUri) {
+        this.type = type;
+        this.defaultName = defaultName;
+        this.defaultDescription = defaultDescription;
+        this.specUri = specUri;
+      }
+
+      @Override
+      public String toString() {
+        return type;
+      }
     }
 
     @XmlElement
@@ -70,6 +106,30 @@
     @XmlElement
     String documentationUri;
 
+    public static AuthenticationSchema oauth() {
+      return fromType(Type.OAUTH);
+    }
+
+    public static AuthenticationSchema oauth2() {
+      return fromType(Type.OAUTH2);
+    }
+    public static AuthenticationSchema oauthBearer() {
+      return fromType(Type.OAUTH_BEARER);
+    }
+    public static AuthenticationSchema httpBasic() {
+      return fromType(Type.HTTP_BASIC);
+    }
+    public static AuthenticationSchema httpDigest() {
+      return fromType(Type.HTTP_DIGEST);
+    }
+
+    private static AuthenticationSchema fromType(Type type) {
+      return new ServiceProviderConfiguration.AuthenticationSchema()
+        .setType(type)
+        .setName(type.defaultName)
+        .setDescription(type.defaultDescription)
+        .setSpecUri(type.specUri);
+    }
   }
 
   @Data