This is an automated email from the ASF dual-hosted git repository.

sseifert pushed a commit to branch feature/SLING-13079-integration-tests
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-jacksonexporter.git

commit f9bf9cf422dfb0a5c46c1a34837ccccd0f9351b8
Author: Stefan Seifert <[email protected]>
AuthorDate: Wed Jan 28 14:18:04 2026 +0100

    SLING-13079 add it java classes
---
 pom.xml                                            |  69 ++++-
 .../it/testbundle/exporter/BaseComponent.java      |  59 ++++
 .../testbundle/exporter/BaseRequestComponent.java  | 101 ++++++
 .../models/it/testbundle/exporter/Component.java   |  26 ++
 .../it/testbundle/exporter/ComponentImpl.java      |  50 +++
 .../testbundle/exporter/DoubledFirstComponent.java |  34 ++
 .../exporter/DoubledSecondComponent.java           |  34 ++
 .../it/testbundle/exporter/ExtendedComponent.java  |  53 ++++
 .../exporter/ExtendedRequestComponent.java         |  59 ++++
 .../testbundle/exporter/RequestComponentImpl.java  |  59 ++++
 .../it/testbundle/exporter/package-info.java       |  21 ++
 .../models/it/testing/exporter/ExporterIT.java     | 344 +++++++++++++++++++++
 12 files changed, 906 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 25e4e77..56bb4f3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,8 +39,10 @@
     </scm>
 
     <properties>
-        <sling.java.version>11</sling.java.version>
         
<project.build.outputTimestamp>2025-06-25T07:05:44Z</project.build.outputTimestamp>
+        <sling.java.version>11</sling.java.version>
+        <models.api.version>1.3.0</models.api.version>
+        <models.impl.version>2.0.1-SNAPSHOT</models.impl.version>
         <version.jackson>2.15.0</version.jackson>
     </properties>
 
@@ -71,13 +73,12 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.models.api</artifactId>
-            <version>1.3.0</version>
+            <version>${models.api.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
-            <version>2.0.17</version>
             <scope>provided</scope>
         </dependency>
 
@@ -170,6 +171,68 @@
             <scope>test</scope>
         </dependency>
 
+        <!-- Integration test dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.junit.core</artifactId>
+            <version>1.2.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.rules</artifactId>
+            <version>2.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.clients</artifactId>
+            <version>3.1.0</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>servlet-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.junit.teleporter</artifactId>
+            <version>1.1.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.johnzon</artifactId>
+            <version>2.0.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.engine</artifactId>
+            <version>3.0.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.github.classgraph</groupId>
+            <artifactId>classgraph</artifactId>
+            <version>4.8.184</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.models.impl</artifactId>
+            <version>${models.impl.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
 
 </project>
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseComponent.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseComponent.java
new file mode 100644
index 0000000..92fcd50
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseComponent.java
@@ -0,0 +1,59 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Exporter;
+import org.apache.sling.models.annotations.Model;
+
+@Model(
+        adaptables = {Resource.class},
+        resourceType = "sling/exp/base")
+@Exporter(name = "jackson", extensions = "json")
+public class BaseComponent {
+
+    private final Resource resource;
+
+    @Inject
+    private String sampleValue;
+
+    public BaseComponent(Resource resource) {
+        this.resource = resource;
+    }
+
+    public String getId() {
+        return this.resource.getPath();
+    }
+
+    public String getSampleValue() {
+        return sampleValue;
+    }
+
+    @JsonProperty(value = "UPPER")
+    public String getSampleValueToUpperCase() {
+        return sampleValue.toUpperCase();
+    }
+
+    public Resource getResource() {
+        return resource;
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseRequestComponent.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseRequestComponent.java
new file mode 100644
index 0000000..b4e868e
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/BaseRequestComponent.java
@@ -0,0 +1,101 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+import javax.inject.Inject;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Exporter;
+import org.apache.sling.models.annotations.ExporterOption;
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.Via;
+import org.apache.sling.models.annotations.injectorspecific.SlingObject;
+
+@Model(
+        adaptables = {SlingHttpServletRequest.class},
+        resourceType = "sling/exp-request/base")
+@Exporter(
+        name = "jackson",
+        extensions = "json",
+        options = {@ExporterOption(name = 
"MapperFeature.SORT_PROPERTIES_ALPHABETICALLY", value = "true")})
+public class BaseRequestComponent {
+
+    @Inject
+    @SlingObject
+    private Resource resource;
+
+    @Inject
+    @Via("resource")
+    private String sampleValue;
+
+    @Inject
+    private Map<String, Object> testBindingsObject;
+
+    @Inject
+    private Map<String, Object> testBindingsObject2;
+
+    private final SlingHttpServletRequest request;
+
+    public BaseRequestComponent(SlingHttpServletRequest request) {
+        this.request = request;
+    }
+
+    public String getId() {
+        return this.resource.getPath();
+    }
+
+    public String getSampleValue() {
+        return sampleValue;
+    }
+
+    @JsonProperty(value = "UPPER")
+    public String getSampleValueToUpperCase() {
+        return sampleValue.toUpperCase();
+    }
+
+    public Resource getResource() {
+        return resource;
+    }
+
+    public Map<String, Object> getTestBindingsObject() {
+        return testBindingsObject;
+    }
+
+    public Map<String, Object> getTestBindingsObject2() {
+        return testBindingsObject2;
+    }
+
+    public SlingHttpServletRequest getSlingHttpServletRequest() {
+        return request;
+    }
+
+    public HttpServletRequest getHttpServletRequest() {
+        return request;
+    }
+
+    public ServletRequest getServletRequest() {
+        return request;
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/Component.java 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/Component.java
new file mode 100644
index 0000000..c022945
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/Component.java
@@ -0,0 +1,26 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+public interface Component {
+
+    String getId();
+
+    String getSampleValue();
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/ComponentImpl.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ComponentImpl.java
new file mode 100644
index 0000000..ad55a83
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ComponentImpl.java
@@ -0,0 +1,50 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Exporter;
+import org.apache.sling.models.annotations.Model;
+
+@Model(
+        adaptables = {Resource.class},
+        adapters = Component.class,
+        resourceType = "sling/exp/interface")
+@Exporter(name = "jackson", extensions = "json")
+public class ComponentImpl implements Component {
+
+    private final Resource resource;
+
+    @Inject
+    private String sampleValue;
+
+    public ComponentImpl(Resource resource) {
+        this.resource = resource;
+    }
+
+    public String getId() {
+        return this.resource.getPath();
+    }
+
+    public String getSampleValue() {
+        return sampleValue;
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledFirstComponent.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledFirstComponent.java
new file mode 100644
index 0000000..58d676f
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledFirstComponent.java
@@ -0,0 +1,34 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Exporter;
+import org.apache.sling.models.annotations.Model;
+
+@Model(
+        adaptables = {Resource.class},
+        resourceType = "sling/exp/doubled")
+@Exporter(name = "jackson", extensions = "json", selector = "firstmodel")
+public class DoubledFirstComponent {
+
+    public String getValue() {
+        return "first";
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledSecondComponent.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledSecondComponent.java
new file mode 100644
index 0000000..bbabb29
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/DoubledSecondComponent.java
@@ -0,0 +1,34 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Exporter;
+import org.apache.sling.models.annotations.Model;
+
+@Model(
+        adaptables = {Resource.class},
+        resourceType = "sling/exp/doubled")
+@Exporter(name = "jackson", extensions = "json", selector = "secondmodel")
+public class DoubledSecondComponent {
+
+    public String getValue() {
+        return "second";
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedComponent.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedComponent.java
new file mode 100644
index 0000000..683dc0a
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedComponent.java
@@ -0,0 +1,53 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Exporter;
+import org.apache.sling.models.annotations.Model;
+
+@Model(
+        adaptables = {Resource.class},
+        resourceType = "sling/exp/extended")
+@Exporter(name = "jackson", extensions = "json")
+public class ExtendedComponent extends BaseComponent {
+
+    @Inject
+    private Date date;
+
+    public ExtendedComponent(Resource resource) {
+        super(resource);
+    }
+
+    public Calendar getDateByCalendar() {
+        Calendar cal = new GregorianCalendar();
+        cal.setTime(date);
+        return cal;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedRequestComponent.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedRequestComponent.java
new file mode 100644
index 0000000..c2c34c4
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/ExtendedRequestComponent.java
@@ -0,0 +1,59 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.models.annotations.Exporter;
+import org.apache.sling.models.annotations.ExporterOption;
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.Via;
+
+@Model(
+        adaptables = {SlingHttpServletRequest.class},
+        resourceType = "sling/exp-request/extended")
+@Exporter(
+        name = "jackson",
+        extensions = "json",
+        options = {@ExporterOption(name = 
"SerializationFeature.WRITE_DATES_AS_TIMESTAMPS", value = "false")})
+public class ExtendedRequestComponent extends BaseRequestComponent {
+
+    @Inject
+    @Via("resource")
+    private Date date;
+
+    public ExtendedRequestComponent(SlingHttpServletRequest request) {
+        super(request);
+    }
+
+    public Calendar getDateByCalendar() {
+        Calendar cal = new GregorianCalendar();
+        cal.setTime(date);
+        return cal;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/RequestComponentImpl.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/RequestComponentImpl.java
new file mode 100644
index 0000000..796b2f6
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/RequestComponentImpl.java
@@ -0,0 +1,59 @@
+/*
+ * 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.sling.models.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Exporter;
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.Via;
+import org.apache.sling.models.annotations.injectorspecific.SlingObject;
+
+@Model(
+        adaptables = {SlingHttpServletRequest.class},
+        adapters = Component.class,
+        resourceType = "sling/exp-request/interface")
+@Exporter(name = "jackson", extensions = "json")
+public class RequestComponentImpl implements Component {
+
+    @Inject
+    @SlingObject
+    private Resource resource;
+
+    @Inject
+    @Via("resource")
+    private String sampleValue;
+
+    @SuppressWarnings("unused")
+    private final SlingHttpServletRequest request;
+
+    public RequestComponentImpl(SlingHttpServletRequest request) {
+        this.request = request;
+    }
+
+    public String getId() {
+        return this.resource.getPath();
+    }
+
+    public String getSampleValue() {
+        return sampleValue;
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/models/it/testbundle/exporter/package-info.java
 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/package-info.java
new file mode 100644
index 0000000..509ddef
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/it/testbundle/exporter/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+@Version("1.0")
+package org.apache.sling.models.it.testbundle.exporter;
+
+import org.osgi.annotation.versioning.Version;
diff --git 
a/src/test/java/org/apache/sling/models/it/testing/exporter/ExporterIT.java 
b/src/test/java/org/apache/sling/models/it/testing/exporter/ExporterIT.java
new file mode 100644
index 0000000..76eb2b5
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/it/testing/exporter/ExporterIT.java
@@ -0,0 +1,344 @@
+/*
+ * 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.sling.models.it.testing.exporter;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.text.Format;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.engine.SlingRequestProcessor;
+import org.apache.sling.junit.rules.TeleporterRule;
+import org.apache.sling.models.factory.MissingExporterException;
+import org.apache.sling.models.factory.ModelFactory;
+import org.apache.sling.models.it.testing.helper.FakeRequest;
+import org.apache.sling.models.it.testing.helper.FakeResponse;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class ExporterIT {
+
+    @Rule
+    public final TeleporterRule teleporter = 
TeleporterRule.forClass(getClass(), "SM_Teleporter");
+
+    private ResourceResolverFactory rrFactory;
+
+    private ModelFactory modelFactory;
+
+    private SlingRequestProcessor slingRequestProcessor;
+
+    private final String baseComponentPath = "/content/exp/baseComponent";
+    private final String doubledComponentPath = 
"/content/exp/doubledComponent";
+    private final String childComponentPath = "/content/exp/childComponent";
+    private final String extendedComponentPath = 
"/content/exp/extendedComponent";
+    private final String interfaceComponentPath = 
"/content/exp/interfaceComponent";
+    private final String baseRequestComponentPath = 
"/content/exp-request/baseComponent";
+    private final String extendedRequestComponentPath = 
"/content/exp-request/extendedComponent";
+    private final String interfaceRequestComponentPath = 
"/content/exp-request/interfaceComponent";
+    private Calendar testDate;
+
+    private Format dateFormat = 
FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZ", 
TimeZone.getTimeZone("UTC"));
+
+    @Before
+    @SuppressWarnings("null")
+    public void setup() throws Exception {
+        rrFactory = teleporter.getService(ResourceResolverFactory.class);
+        modelFactory = teleporter.getService(ModelFactory.class);
+        slingRequestProcessor = 
teleporter.getService(SlingRequestProcessor.class);
+
+        try (ResourceResolver adminResolver = 
rrFactory.getServiceResourceResolver(null); ) {
+            Map<String, Object> properties = new HashMap<String, Object>();
+            properties.put("sampleValue", "baseTESTValue");
+            properties.put("sampleBooleanValue", true);
+            properties.put("sampleLongValue", 1l);
+            properties.put("sampleDoubleValue", 1d);
+            properties.put("sampleArray", new String[] {"a", "b", "c"});
+            properties.put("sampleEmptyArray", new String[0]);
+            properties.put("sampleBinary", new 
ByteArrayInputStream("abc".getBytes("UTF-8")));
+            properties.put("sampleBinaryArray", new InputStream[] {
+                new ByteArrayInputStream("abc".getBytes("UTF-8")), new 
ByteArrayInputStream("def".getBytes("UTF-8"))
+            });
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_TYPE, "sling/exp/base");
+            ResourceUtil.getOrCreateResource(adminResolver, baseComponentPath, 
properties, null, false);
+
+            ResourceUtil.getOrCreateResource(
+                    adminResolver, baseComponentPath + "/child", 
Collections.<String, Object>emptyMap(), null, false);
+
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_TYPE,
+                    "sling/exp-request/base");
+            ResourceUtil.getOrCreateResource(adminResolver, 
baseRequestComponentPath, properties, null, false);
+            properties.clear();
+
+            properties.put("sampleValue", "childTESTValue");
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_TYPE, "sling/exp/child");
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE,
+                    "sling/exp/base");
+            ResourceUtil.getOrCreateResource(adminResolver, 
childComponentPath, properties, null, false);
+            properties.clear();
+
+            properties.put("sampleValue", "extendedTESTValue");
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_TYPE,
+                    "sling/exp/extended");
+            testDate = Calendar.getInstance();
+            testDate.setTimeZone(TimeZone.getTimeZone("UTC"));
+            testDate.setTimeInMillis(0);
+            testDate.set(2015, 6, 29);
+            properties.put("date", testDate);
+            ResourceUtil.getOrCreateResource(adminResolver, 
extendedComponentPath, properties, null, false);
+
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_TYPE,
+                    "sling/exp-request/extended");
+            ResourceUtil.getOrCreateResource(adminResolver, 
extendedRequestComponentPath, properties, null, false);
+            properties.clear();
+
+            properties.put("sampleValue", "interfaceTESTValue");
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_TYPE,
+                    "sling/exp/interface");
+            ResourceUtil.getOrCreateResource(adminResolver, 
interfaceComponentPath, properties, null, false);
+
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_TYPE,
+                    "sling/exp-request/interface");
+            ResourceUtil.getOrCreateResource(adminResolver, 
interfaceRequestComponentPath, properties, null, false);
+            properties.clear();
+
+            properties.put(
+                    SlingConstants.NAMESPACE_PREFIX + ":" + 
SlingConstants.PROPERTY_RESOURCE_TYPE, "sling/exp/doubled");
+            ResourceUtil.getOrCreateResource(adminResolver, 
doubledComponentPath, properties, null, false);
+
+            adminResolver.commit();
+        }
+    }
+
+    @Test
+    @SuppressWarnings("null")
+    public void testExportToJSON() throws Exception {
+        try (ResourceResolver resolver = 
rrFactory.getServiceResourceResolver(null); ) {
+            final Resource baseComponentResource = 
resolver.getResource(baseComponentPath);
+            Assert.assertNotNull(baseComponentResource);
+            String jsonData = modelFactory.exportModelForResource(
+                    baseComponentResource, "jackson", String.class, 
Collections.<String, String>emptyMap());
+            Assert.assertTrue(
+                    "JSON Data should contain the property value", 
StringUtils.contains(jsonData, "baseTESTValue"));
+
+            JsonObject parsed = Json.createReader(new 
StringReader(jsonData)).readObject();
+            JsonObject resource = parsed.getJsonObject("resource");
+            Assert.assertEquals(3, 
resource.getJsonArray("sampleArray").size());
+            Assert.assertEquals(
+                    1.0d, 
resource.getJsonNumber("sampleDoubleValue").doubleValue(), .1);
+            Assert.assertEquals(2, 
resource.getJsonArray(":sampleBinaryArray").size());
+            Assert.assertTrue(resource.getBoolean("sampleBooleanValue"));
+            Assert.assertEquals(1, resource.getInt("sampleLongValue"));
+            Assert.assertEquals(3, resource.getInt(":sampleBinary"));
+            Assert.assertEquals(0, 
resource.getJsonArray("sampleEmptyArray").size());
+
+            final Resource extendedComponentResource = 
resolver.getResource(extendedComponentPath);
+            Assert.assertNotNull(extendedComponentResource);
+            jsonData = modelFactory.exportModelForResource(
+                    extendedComponentResource, "jackson", String.class, 
Collections.<String, String>emptyMap());
+            Assert.assertTrue(
+                    "JSON Data should contain the property value", 
StringUtils.contains(jsonData, "extendedTESTValue"));
+
+            final Resource interfaceComponentResource = 
resolver.getResource(interfaceComponentPath);
+            Assert.assertNotNull(baseComponentResource);
+            jsonData = modelFactory.exportModelForResource(
+                    interfaceComponentResource, "jackson", String.class, 
Collections.<String, String>emptyMap());
+            Assert.assertTrue(
+                    "JSON Data should contain the property value",
+                    StringUtils.contains(jsonData, "interfaceTESTValue"));
+        }
+    }
+
+    @Test
+    public void testExportToTidyJSON() throws Exception {
+        try (ResourceResolver resolver = 
rrFactory.getServiceResourceResolver(null); ) {
+            final Resource baseComponentResource = 
resolver.getResource(baseComponentPath);
+            Assert.assertNotNull(baseComponentResource);
+            String jsonData = modelFactory.exportModelForResource(
+                    baseComponentResource, "jackson", String.class, 
Collections.<String, String>emptyMap());
+            Assert.assertFalse(jsonData.contains(System.lineSeparator()));
+
+            jsonData = modelFactory.exportModelForResource(
+                    baseComponentResource,
+                    "jackson",
+                    String.class,
+                    Collections.<String, String>singletonMap("tidy", "true"));
+            Assert.assertTrue(jsonData.contains(System.lineSeparator()));
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testExportToMap() throws Exception {
+        try (ResourceResolver resolver = 
rrFactory.getServiceResourceResolver(null); ) {
+            final Resource baseComponentResource = 
resolver.getResource(baseComponentPath);
+            Assert.assertNotNull(baseComponentResource);
+            Map<String, Object> data = modelFactory.exportModelForResource(
+                    baseComponentResource, "jackson", Map.class, 
Collections.<String, String>emptyMap());
+            Assert.assertEquals("Should have resource value", "baseTESTValue", 
data.get("sampleValue"));
+            Assert.assertEquals("Should have resource value", "BASETESTVALUE", 
data.get("UPPER"));
+        }
+    }
+
+    @Test
+    public void testResourceServlets() throws Exception {
+        try (ResourceResolver resolver = 
rrFactory.getServiceResourceResolver(null); ) {
+            FakeResponse response = new FakeResponse();
+            slingRequestProcessor.processRequest(
+                    new FakeRequest(baseComponentPath + ".model.json"), 
response, resolver);
+            JsonObject obj = Json.createReader(
+                            new 
StringReader((response.getStringWriter().toString())))
+                    .readObject();
+            Assert.assertEquals("application/json", response.getContentType());
+            Assert.assertEquals("UTF-8", response.getCharacterEncoding());
+            Assert.assertEquals("BASETESTVALUE", obj.getString("UPPER"));
+            Assert.assertEquals(baseComponentPath, obj.getString("id"));
+
+            response = new FakeResponse();
+            slingRequestProcessor.processRequest(
+                    new FakeRequest(extendedComponentPath + ".model.json"), 
response, resolver);
+            obj = Json.createReader(new 
StringReader((response.getStringWriter().toString())))
+                    .readObject();
+            Assert.assertEquals("application/json", response.getContentType());
+            Assert.assertEquals("UTF-8", response.getCharacterEncoding());
+            Assert.assertEquals(extendedComponentPath, obj.getString("id"));
+            Assert.assertEquals(
+                    testDate.getTimeInMillis(), 
obj.getJsonNumber("date").longValue());
+
+            response = new FakeResponse();
+            slingRequestProcessor.processRequest(
+                    new FakeRequest(interfaceComponentPath + ".model.json"), 
response, resolver);
+            obj = Json.createReader(new 
StringReader((response.getStringWriter().toString())))
+                    .readObject();
+            Assert.assertEquals("application/json", response.getContentType());
+            Assert.assertEquals("UTF-8", response.getCharacterEncoding());
+            Assert.assertEquals(interfaceComponentPath, obj.getString("id"));
+            Assert.assertEquals("interfaceTESTValue", 
obj.getString("sampleValue"));
+        }
+    }
+
+    @Test
+    public void testRequestServlets() throws Exception {
+        try (ResourceResolver resolver = 
rrFactory.getServiceResourceResolver(null); ) {
+            FakeResponse response = new FakeResponse();
+            slingRequestProcessor.processRequest(
+                    new FakeRequest(baseRequestComponentPath + ".model.json"), 
response, resolver);
+            String stringOutput = response.getStringWriter().toString();
+
+            Assert.assertTrue(stringOutput.startsWith("{\"UPPER\":"));
+
+            JsonObject obj = Json.createReader(new 
StringReader(stringOutput)).readObject();
+            Assert.assertEquals("application/json", response.getContentType());
+            Assert.assertEquals("UTF-8", response.getCharacterEncoding());
+            Assert.assertEquals("BASETESTVALUE", obj.getString("UPPER"));
+            Assert.assertTrue(obj.containsKey("testBindingsObject"));
+            JsonObject testBindingsObject = 
obj.getJsonObject("testBindingsObject");
+            Assert.assertEquals("value", testBindingsObject.getString("name"));
+            Assert.assertTrue(obj.containsKey("testBindingsObject2"));
+            JsonObject testBindingsObject2 = 
obj.getJsonObject("testBindingsObject2");
+            Assert.assertEquals("value2", 
testBindingsObject2.getString("name2"));
+            Assert.assertEquals(baseRequestComponentPath, obj.getString("id"));
+
+            response = new FakeResponse();
+            slingRequestProcessor.processRequest(
+                    new FakeRequest(extendedRequestComponentPath + 
".model.json"), response, resolver);
+            obj = Json.createReader(new 
StringReader((response.getStringWriter().toString())))
+                    .readObject();
+            Assert.assertEquals("application/json", response.getContentType());
+            Assert.assertEquals("UTF-8", response.getCharacterEncoding());
+            Assert.assertEquals(extendedRequestComponentPath, 
obj.getString("id"));
+            Assert.assertEquals(dateFormat.format(testDate), 
obj.getString("date"));
+
+            response = new FakeResponse();
+            slingRequestProcessor.processRequest(
+                    new FakeRequest(interfaceRequestComponentPath + 
".model.json"), response, resolver);
+            obj = Json.createReader(new 
StringReader((response.getStringWriter().toString())))
+                    .readObject();
+            Assert.assertEquals("application/json", response.getContentType());
+            Assert.assertEquals("UTF-8", response.getCharacterEncoding());
+            Assert.assertEquals(interfaceRequestComponentPath, 
obj.getString("id"));
+            Assert.assertEquals("interfaceTESTValue", 
obj.getString("sampleValue"));
+        }
+    }
+
+    @Test
+    public void testDoubledServlets() throws Exception {
+        try (ResourceResolver resolver = 
rrFactory.getServiceResourceResolver(null); ) {
+            FakeResponse response = new FakeResponse();
+            slingRequestProcessor.processRequest(
+                    new FakeRequest(doubledComponentPath + 
".firstmodel.json"), response, resolver);
+
+            JsonObject obj = Json.createReader(
+                            new 
StringReader((response.getStringWriter().toString())))
+                    .readObject();
+            Assert.assertEquals("application/json", response.getContentType());
+            Assert.assertEquals("first", obj.getString("value"));
+
+            response = new FakeResponse();
+            slingRequestProcessor.processRequest(
+                    new FakeRequest(doubledComponentPath + 
".secondmodel.json"), response, resolver);
+            obj = Json.createReader(new 
StringReader((response.getStringWriter().toString())))
+                    .readObject();
+            Assert.assertEquals("application/json", response.getContentType());
+            Assert.assertEquals("second", obj.getString("value"));
+        }
+    }
+
+    @Test
+    public void testFailedExport() throws Exception {
+        boolean thrown = false;
+        try {
+            try (ResourceResolver resolver = 
rrFactory.getServiceResourceResolver(null); ) {
+                final Resource baseComponentResource = 
resolver.getResource(baseComponentPath);
+                Assert.assertNotNull(baseComponentResource);
+                modelFactory.exportModelForResource(
+                        baseComponentResource, "jaxb", String.class, 
Collections.<String, String>emptyMap());
+                Assert.fail("Should have thrown missing serializer error.");
+            }
+        } catch (MissingExporterException e) {
+            thrown = true;
+            Assert.assertEquals("No exporter named jaxb supports 
java.lang.String.", e.getMessage());
+        }
+        Assert.assertTrue(thrown);
+    }
+}


Reply via email to