This is an automated email from the ASF dual-hosted git repository.
sseifert pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-jacksonexporter.git
The following commit(s) were added to refs/heads/master by this push:
new 9e70224 SLING-13079 Include Integration Tests (#17)
9e70224 is described below
commit 9e70224a2aac0b27f0bad972f63d76f8c11eb0dd
Author: Stefan Seifert <[email protected]>
AuthorDate: Thu Jan 29 20:33:30 2026 +0100
SLING-13079 Include Integration Tests (#17)
---
pom.xml | 338 +++++++++++++++++-
src/test/it-features/it-launcher-repoinit.txt | 23 ++
src/test/it-features/it-launcher.json | 34 ++
.../customizers/SM_TeleporterCustomizer.java | 61 ++++
.../jacksonexporter/it/GenerateTestBundle.java | 92 +++++
.../it/testbundle/exporter/BaseComponent.java | 59 ++++
.../testbundle/exporter/BaseRequestComponent.java | 105 ++++++
.../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 | 62 ++++
.../exporter/JakartaBaseRequestComponent.java | 105 ++++++
.../exporter/JakartaExtendedRequestComponent.java | 62 ++++
.../exporter/JakartaRequestComponentImpl.java | 59 ++++
.../testbundle/exporter/RequestComponentImpl.java | 59 ++++
.../AnotherTestBindingsValuesProvider.java | 36 ++
.../services/TestBindingsValuesProvider.java | 36 ++
.../it/testing/exporter/ExporterIT.java | 393 +++++++++++++++++++++
20 files changed, 1717 insertions(+), 4 deletions(-)
diff --git a/pom.xml b/pom.xml
index 25e4e77..f3ff686 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,9 +39,16 @@
</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>
+ <!-- integration tests -->
+ <sling.starter.version>14-SNAPSHOT</sling.starter.version>
+ <starter.min.bundles.count>200</starter.min.bundles.count>
+ <it.startTimeoutSeconds>60</it.startTimeoutSeconds>
+ <it.models.log.level>debug</it.models.log.level>
</properties>
<dependencies>
@@ -71,13 +78,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>
@@ -160,7 +166,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.sling-mock.junit5</artifactId>
- <version>3.5.6</version>
+ <version>4.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -170,6 +176,330 @@
<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>jakarta.json</groupId>
+ <artifactId>jakarta.json-api</artifactId>
+ <version>2.1.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.johnzon</groupId>
+ <artifactId>johnzon-core</artifactId>
+ <version>2.0.2</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>
+ <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>
+ <build>
+ <plugins>
+
+ <!-- Generate IT Test Bundle on the fly via TinyBundles -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>3.6.3</version>
+ <executions>
+ <execution>
+ <id>generate-it-testbundle</id>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ <configuration>
+ <classpathScope>test</classpathScope>
+
<mainClass>org.apache.sling.models.jacksonexporter.it.GenerateTestBundle</mainClass>
+ <arguments>
+
<argument>${project.build.directory}/it-testbundle.jar</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>reserve-network-port</id>
+ <goals>
+ <goal>reserve-network-port</goal>
+ </goals>
+ <phase>initialize</phase>
+ <configuration>
+ <portNames>
+ <portName>http.port</portName>
+ <portName>jacoco.port</portName>
+ </portNames>
+ </configuration>
+ </execution>
+ <execution>
+ <id>attach-it-testbundle</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+
<file>${project.build.directory}/it-testbundle.jar</file>
+ <type>jar</type>
+ <classifier>it-testbundle</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <!--
+ Record integration test code coverage via jacoco, using
TCP server
+ We cannot rely on the default file-based approach as the
sling JVM is stopped forcefully, preventing proper file write on shutdown.
+ -->
+ <execution>
+ <id>prepare-agent-integration-launcher</id>
+ <goals>
+ <goal>prepare-agent-integration</goal>
+ </goals>
+ <configuration>
+
<propertyName>jacoco.launcher.command</propertyName>
+ <output>tcpserver</output>
+ <address>localhost</address>
+ <port>${jacoco.port}</port>
+ </configuration>
+ </execution>
+ <execution>
+ <id>dump-coverage-launcher</id>
+ <goals>
+ <goal>dump</goal>
+ </goals>
+ <phase>post-integration-test</phase>
+ <configuration>
+ <address>localhost</address>
+ <port>${jacoco.port}</port>
+
<destFile>${project.build.directory}/jacoco-it.exec</destFile>
+ <append>true</append>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>slingfeature-maven-plugin</artifactId>
+ <version>1.9.2</version>
+ <extensions>true</extensions>
+ <configuration>
+ <features>src/test/it-features</features>
+
<replacePropertyVariables>models.api.version,models.impl.version,it.models.log.level</replacePropertyVariables>
+
<skipAddFeatureDependencies>true</skipAddFeatureDependencies>
+ <aggregates>
+ <aggregate>
+ <classifier>it-app</classifier>
+ <filesInclude>*.json</filesInclude>
+ <variablesOverrides>
+ <http.port>${http.port}</http.port>
+ </variablesOverrides>
+ <artifactsOverrides>
+
<artifactsOverride>org.apache.sling:org.apache.sling.models.api:HIGHEST</artifactsOverride>
+
<artifactsOverride>org.apache.sling:org.apache.sling.models.impl:HIGHEST</artifactsOverride>
+
<artifactsOverride>org.apache.sling:org.apache.sling.models.jacksonexporter:HIGHEST</artifactsOverride>
+ </artifactsOverrides>
+ <includeArtifact>
+ <groupId>org.apache.sling</groupId>
+
<artifactId>org.apache.sling.starter</artifactId>
+ <classifier>nosample_base</classifier>
+ <version>${sling.starter.version}</version>
+ <type>slingosgifeature</type>
+ </includeArtifact>
+ <includeArtifact>
+ <groupId>org.apache.sling</groupId>
+
<artifactId>org.apache.sling.starter</artifactId>
+ <classifier>oak_persistence_sns</classifier>
+ <version>${sling.starter.version}</version>
+ <type>slingosgifeature</type>
+ </includeArtifact>
+ <includeArtifact>
+ <groupId>org.apache.sling</groupId>
+
<artifactId>org.apache.sling.starter</artifactId>
+ <classifier>junit</classifier>
+ <version>${sling.starter.version}</version>
+ <type>slingosgifeature</type>
+ </includeArtifact>
+ </aggregate>
+ </aggregates>
+ <scans>
+ <scan>
+ <includeClassifier>it-app</includeClassifier>
+ </scan>
+ </scans>
+ </configuration>
+ <executions>
+ <execution>
+ <id>prepare-features</id>
+ <goals>
+ <goal>aggregate-features</goal>
+ <goal>analyse-features</goal>
+ <goal>attach-features</goal>
+ </goals>
+ <phase>pre-integration-test</phase>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>feature-launcher-maven-plugin</artifactId>
+ <version>1.0.3-SNAPSHOT</version>
+ <configuration>
+ <launches>
+ <launch>
+ <id>sling-starter-oak-tar</id>
+ <feature>
+ <groupId>org.apache.sling</groupId>
+
<artifactId>org.apache.sling.models.jacksonexporter</artifactId>
+ <version>${project.version}</version>
+ <classifier>it-app</classifier>
+ <type>slingosgifeature</type>
+ </feature>
+ <launcherArguments>
+ <vmOptions>
+ <value>--add-opens
java.base/java.lang=ALL-UNNAMED</value>
+ <value>${jacoco.launcher.command}</value>
+ </vmOptions>
+ <frameworkProperties>
+
<org.osgi.service.http.port>${http.port}</org.osgi.service.http.port>
+
<org.apache.felix.http.jetty.responseBufferSize>5000000</org.apache.felix.http.jetty.responseBufferSize>
+ </frameworkProperties>
+ </launcherArguments>
+
<startTimeoutSeconds>${it.startTimeoutSeconds}</startTimeoutSeconds>
+ </launch>
+ </launches>
+ </configuration>
+ <executions>
+ <execution>
+ <id>launcher-start</id>
+ <goals>
+ <goal>start</goal>
+ <goal>stop</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+
<launchpad.http.server.url>http://localhost:${http.port}</launchpad.http.server.url>
+
<starter.http.test.ports>false:${http.port}</starter.http.test.ports>
+
<starter.min.bundles.count>${starter.min.bundles.count}</starter.min.bundles.count>
+ <!-- Comma-separated list of paths to check for 200
status -->
+
<starter.check.paths>/system/console/bundles,</starter.check.paths>
+ </systemPropertyVariables>
+ </configuration>
+ <dependencies>
+ <!-- Uss JUnit 4 for integration tests -->
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-junit47</artifactId>
+ <version>3.5.4</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>integration-test</id>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <profiles>
+ <!--
+ Debugging profile:
+ - Run on port 8080 (not random port)
+ - Waits for user input after tests are completed to allow inspection
before shutting down the Sling instance
+ - Sets log level for Sling Models to DEBUG
+ -->
+ <profile>
+ <id>it-debug</id>
+ <properties>
+ <http.port>8080</http.port>
+
<feature-launcher.waitForInput>true</feature-launcher.waitForInput>
+ <it.models.log.level>debug</it.models.log.level>
+ </properties>
+ </profile>
+ </profiles>
+
</project>
diff --git a/src/test/it-features/it-launcher-repoinit.txt
b/src/test/it-features/it-launcher-repoinit.txt
new file mode 100644
index 0000000..7d36118
--- /dev/null
+++ b/src/test/it-features/it-launcher-repoinit.txt
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+create service user models-it
+set ACL for models-it
+ allow jcr:all on /
+end
\ No newline at end of file
diff --git a/src/test/it-features/it-launcher.json
b/src/test/it-features/it-launcher.json
new file mode 100644
index 0000000..ff9bbb8
--- /dev/null
+++ b/src/test/it-features/it-launcher.json
@@ -0,0 +1,34 @@
+{
+ "bundles": [
+ {
+ "id":
"org.apache.sling/org.apache.sling.models.api/${models.api.version}",
+ "start-order": 20
+ },
+ {
+ "id":
"org.apache.sling/org.apache.sling.models.impl/${models.impl.version}",
+ "start-order": 20
+ },
+ {
+ "id":
"org.apache.sling/org.apache.sling.models.jacksonexporter/${project.version}",
+ "start-order": 20
+ },
+ {
+ "id":
"org.apache.sling/org.apache.sling.models.jacksonexporter/${project.version}//it-testbundle",
+ "start-order": 20
+ }
+ ],
+ "configurations": {
+
"org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~integration-tests":
{
+ "user.mapping": [
+ "org.apache.sling.junit.core=models-it"
+ ]
+ },
+
"org.apache.sling.commons.log.LogManager.factory.config~integration-tests": {
+ "org.apache.sling.commons.log.names": [
+ "org.apache.sling.models"
+ ],
+ "org.apache.sling.commons.log.level": "${it.models.log.level}"
+ }
+ },
+ "repoinit:TEXT|true": "@file"
+}
\ No newline at end of file
diff --git
a/src/test/java/org/apache/sling/junit/teleporter/customizers/SM_TeleporterCustomizer.java
b/src/test/java/org/apache/sling/junit/teleporter/customizers/SM_TeleporterCustomizer.java
new file mode 100644
index 0000000..b506364
--- /dev/null
+++
b/src/test/java/org/apache/sling/junit/teleporter/customizers/SM_TeleporterCustomizer.java
@@ -0,0 +1,61 @@
+/*
+ * 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.junit.teleporter.customizers;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.sling.junit.rules.TeleporterRule;
+import org.apache.sling.models.impl.ModelAdapterFactory;
+import org.apache.sling.models.jacksonexporter.impl.JacksonExporter;
+import org.apache.sling.testing.clients.ClientException;
+import org.apache.sling.testing.clients.osgi.OsgiConsoleClient;
+import org.apache.sling.testing.serversetup.instance.SlingTestBase;
+import org.apache.sling.testing.teleporter.client.ClientSideTeleporter;
+import org.apache.sling.testing.timeouts.TimeoutsProvider;
+
+/** This is required by the TeleporterRule, to setup the client-side
+ * teleporter with (at least) the test server URL.
+ */
+public class SM_TeleporterCustomizer implements TeleporterRule.Customizer {
+
+ private static final SlingTestBase S = new SlingTestBase();
+
+ private static final Class[] EXPECTED_COMPONENTS = new Class[]
{ModelAdapterFactory.class, JacksonExporter.class};
+
+ @Override
+ public void customize(TeleporterRule t, String options) {
+ final ClientSideTeleporter cst = (ClientSideTeleporter) t;
+ cst.setBaseUrl(S.getServerBaseUrl());
+ cst.setServerCredentials(S.getServerUsername(), S.getServerPassword());
+
cst.setTestReadyTimeoutSeconds(TimeoutsProvider.getInstance().getTimeout(5));
+ cst.includeDependencyPrefix("org.apache.sling.models.it.testing");
+
+ // additionally check for the registration of mandatory sling models
components
+ try (OsgiConsoleClient osgiClient =
+ new OsgiConsoleClient(URI.create(S.getServerBaseUrl()),
S.getServerUsername(), S.getServerPassword())) {
+ for (Class clazz : EXPECTED_COMPONENTS) {
+ osgiClient.waitComponentRegistered(clazz.getName(), 20000,
200);
+ }
+ } catch (ClientException | TimeoutException | InterruptedException |
IOException ex) {
+ throw new RuntimeException("Error waiting for expected
components.", ex);
+ }
+ }
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/GenerateTestBundle.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/GenerateTestBundle.java
new file mode 100644
index 0000000..b6cf45d
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/GenerateTestBundle.java
@@ -0,0 +1,92 @@
+/*
+ * 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.jacksonexporter.it;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import io.github.classgraph.ClassGraph;
+import io.github.classgraph.ClassInfo;
+import io.github.classgraph.ScanResult;
+import org.apache.sling.models.annotations.Model;
+import org.ops4j.pax.tinybundles.TinyBundle;
+import org.ops4j.pax.tinybundles.TinyBundles;
+import org.osgi.framework.Constants;
+
+/**
+ * This uses tinybundles to create a test bundle that is deployed to sling
+ * starter. The test bundle contains all classes from the packages
+ * org.apache.sling.models.it.testbundle.*
+ */
+public class GenerateTestBundle {
+
+ private static final String DUMMY_TEXT = "Dummy file for Integration Test
bundle.";
+
+ public static void main(String[] args) throws Exception {
+ Path outputFile = Paths.get(args[0]);
+ try (InputStream bundleStream =
createBundle().build(TinyBundles.bndBuilder())) {
+ Files.copy(bundleStream, outputFile);
+ }
+ System.out.println("Test bundle created at " +
outputFile.toAbsolutePath());
+ }
+
+ static TinyBundle createBundle() {
+ TinyBundle bundle = TinyBundles.bundle()
+ .setHeader(Constants.BUNDLE_NAME, "Apache Sling Models Jackson
Exporter - IT Test Bundle")
+ .setHeader(Constants.BUNDLE_VERSION, "1.0.0-SNAPSHOT")
+ .setHeader(Constants.EXPORT_PACKAGE,
"org.apache.sling.models.jacksonexporter.it.testbundle.*")
+ // add dummy files to please verify-legal-files check
+ .addResource("META-INF/LICENSE", new
ByteArrayInputStream(DUMMY_TEXT.getBytes(StandardCharsets.UTF_8)))
+ .addResource("META-INF/NOTICE", new
ByteArrayInputStream(DUMMY_TEXT.getBytes(StandardCharsets.UTF_8)));
+
+ // add all testbundle classes
+ Set<String> modelClassNames = new TreeSet<>();
+ getAllClasses().forEach(clazz -> {
+ bundle.addClass(clazz);
+ if (clazz.isAnnotationPresent(Model.class)) {
+ modelClassNames.add(clazz.getName());
+ }
+ });
+
+ // register sling models
+ bundle.setHeader("Sling-Model-Classes",
modelClassNames.stream().collect(Collectors.joining(",")));
+
+ return bundle;
+ }
+
+ /**
+ * Dynamically find all classes in classpath under package(s)
org.apache.sling.models.it.testbundle.*
+ */
+ static List<Class<?>> getAllClasses() {
+ try (ScanResult scanResult = new ClassGraph()
+ .enableClassInfo()
+
.acceptPackages("org.apache.sling.models.jacksonexporter.it.testbundle")
+ .scan()) {
+ return
scanResult.getAllClasses().stream().map(ClassInfo::loadClass).collect(Collectors.toList());
+ }
+ }
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/BaseComponent.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/BaseComponent.java
new file mode 100644
index 0000000..f6b7bbd
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/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.jacksonexporter.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/jacksonexporter/it/testbundle/exporter/BaseRequestComponent.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/BaseRequestComponent.java
new file mode 100644
index 0000000..1775f71
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/BaseRequestComponent.java
@@ -0,0 +1,105 @@
+/*
+ * 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.jacksonexporter.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.JsonIgnore;
+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;
+ }
+
+ @JsonIgnore
+ public SlingHttpServletRequest getSlingHttpServletRequest() {
+ return request;
+ }
+
+ @JsonIgnore
+ public HttpServletRequest getHttpServletRequest() {
+ return request;
+ }
+
+ @JsonIgnore
+ public ServletRequest getServletRequest() {
+ return request;
+ }
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/Component.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/Component.java
new file mode 100644
index 0000000..d83af0b
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/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.jacksonexporter.it.testbundle.exporter;
+
+public interface Component {
+
+ String getId();
+
+ String getSampleValue();
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/ComponentImpl.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/ComponentImpl.java
new file mode 100644
index 0000000..1e8773f
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/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.jacksonexporter.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/jacksonexporter/it/testbundle/exporter/DoubledFirstComponent.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/DoubledFirstComponent.java
new file mode 100644
index 0000000..3d76e37
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/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.jacksonexporter.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/jacksonexporter/it/testbundle/exporter/DoubledSecondComponent.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/DoubledSecondComponent.java
new file mode 100644
index 0000000..d79ab33
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/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.jacksonexporter.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/jacksonexporter/it/testbundle/exporter/ExtendedComponent.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/ExtendedComponent.java
new file mode 100644
index 0000000..ecb11e6
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/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.jacksonexporter.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/jacksonexporter/it/testbundle/exporter/ExtendedRequestComponent.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/ExtendedRequestComponent.java
new file mode 100644
index 0000000..df3ec1b
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/ExtendedRequestComponent.java
@@ -0,0 +1,62 @@
+/*
+ * 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.jacksonexporter.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+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);
+ }
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern =
"yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")
+ public Calendar getDateByCalendar() {
+ Calendar cal = new GregorianCalendar();
+ cal.setTime(date);
+ return cal;
+ }
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern =
"yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")
+ public Date getDate() {
+ return date;
+ }
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaBaseRequestComponent.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaBaseRequestComponent.java
new file mode 100644
index 0000000..a9e1178
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaBaseRequestComponent.java
@@ -0,0 +1,105 @@
+/*
+ * 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.jacksonexporter.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
+import org.apache.sling.api.SlingJakartaHttpServletRequest;
+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 = {SlingJakartaHttpServletRequest.class},
+ resourceType = "sling/exp-request/baseJakarta")
+@Exporter(
+ name = "jackson",
+ extensions = "json",
+ options = {@ExporterOption(name =
"MapperFeature.SORT_PROPERTIES_ALPHABETICALLY", value = "true")})
+public class JakartaBaseRequestComponent {
+
+ @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 SlingJakartaHttpServletRequest request;
+
+ public JakartaBaseRequestComponent(SlingJakartaHttpServletRequest 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;
+ }
+
+ @JsonIgnore
+ public SlingJakartaHttpServletRequest getSlingHttpServletRequest() {
+ return request;
+ }
+
+ @JsonIgnore
+ public HttpServletRequest getHttpServletRequest() {
+ return request;
+ }
+
+ @JsonIgnore
+ public ServletRequest getServletRequest() {
+ return request;
+ }
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaExtendedRequestComponent.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaExtendedRequestComponent.java
new file mode 100644
index 0000000..c2edd58
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaExtendedRequestComponent.java
@@ -0,0 +1,62 @@
+/*
+ * 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.jacksonexporter.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.sling.api.SlingJakartaHttpServletRequest;
+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 = {SlingJakartaHttpServletRequest.class},
+ resourceType = "sling/exp-request/extendedJakarta")
+@Exporter(
+ name = "jackson",
+ extensions = "json",
+ options = {@ExporterOption(name =
"SerializationFeature.WRITE_DATES_AS_TIMESTAMPS", value = "false")})
+public class JakartaExtendedRequestComponent extends
JakartaBaseRequestComponent {
+
+ @Inject
+ @Via("resource")
+ private Date date;
+
+ public JakartaExtendedRequestComponent(SlingJakartaHttpServletRequest
request) {
+ super(request);
+ }
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern =
"yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")
+ public Calendar getDateByCalendar() {
+ Calendar cal = new GregorianCalendar();
+ cal.setTime(date);
+ return cal;
+ }
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern =
"yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")
+ public Date getDate() {
+ return date;
+ }
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaRequestComponentImpl.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaRequestComponentImpl.java
new file mode 100644
index 0000000..3522422
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/JakartaRequestComponentImpl.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.jacksonexporter.it.testbundle.exporter;
+
+import javax.inject.Inject;
+
+import org.apache.sling.api.SlingJakartaHttpServletRequest;
+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 = {SlingJakartaHttpServletRequest.class},
+ adapters = Component.class,
+ resourceType = "sling/exp-request/interfaceJakarta")
+@Exporter(name = "jackson", extensions = "json")
+public class JakartaRequestComponentImpl implements Component {
+
+ @Inject
+ @SlingObject
+ private Resource resource;
+
+ @Inject
+ @Via("resource")
+ private String sampleValue;
+
+ @SuppressWarnings("unused")
+ private final SlingJakartaHttpServletRequest request;
+
+ public JakartaRequestComponentImpl(SlingJakartaHttpServletRequest 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/jacksonexporter/it/testbundle/exporter/RequestComponentImpl.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/exporter/RequestComponentImpl.java
new file mode 100644
index 0000000..7fa3687
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/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.jacksonexporter.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/jacksonexporter/it/testbundle/services/AnotherTestBindingsValuesProvider.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/services/AnotherTestBindingsValuesProvider.java
new file mode 100644
index 0000000..39bee94
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/services/AnotherTestBindingsValuesProvider.java
@@ -0,0 +1,36 @@
+/*
+ * 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.jacksonexporter.it.testbundle.services;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.service.component.annotations.Component;
+
+@Component(
+ service = Map.class,
+ property = {"javax.script.name=sling-models-exporter"})
+public class AnotherTestBindingsValuesProvider extends HashMap<String, Object>
{
+ private static final long serialVersionUID = 1L;
+
+ public AnotherTestBindingsValuesProvider() {
+ super.put("testBindingsObject2", Collections.singletonMap("name2",
"value2"));
+ }
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/services/TestBindingsValuesProvider.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/services/TestBindingsValuesProvider.java
new file mode 100644
index 0000000..cae26bd
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testbundle/services/TestBindingsValuesProvider.java
@@ -0,0 +1,36 @@
+/*
+ * 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.jacksonexporter.it.testbundle.services;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.service.component.annotations.Component;
+
+@Component(
+ service = Map.class,
+ property = {"javax.script.name=*"})
+public class TestBindingsValuesProvider extends HashMap<String, Object> {
+ private static final long serialVersionUID = -5029445376678233701L;
+
+ public TestBindingsValuesProvider() {
+ super.put("testBindingsObject", Collections.singletonMap("name",
"value"));
+ }
+}
diff --git
a/src/test/java/org/apache/sling/models/jacksonexporter/it/testing/exporter/ExporterIT.java
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testing/exporter/ExporterIT.java
new file mode 100644
index 0000000..900016f
--- /dev/null
+++
b/src/test/java/org/apache/sling/models/jacksonexporter/it/testing/exporter/ExporterIT.java
@@ -0,0 +1,393 @@
+/*
+ * 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.jacksonexporter.it.testing.exporter;
+
+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 jakarta.json.Json;
+import jakarta.json.JsonObject;
+import org.apache.commons.lang3.Strings;
+import org.apache.commons.lang3.time.FastDateFormat;
+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.apache.sling.models.it.testing.helper.JakartaFakeRequest;
+import org.apache.sling.models.it.testing.helper.JakartaFakeResponse;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static
org.apache.sling.api.resource.ResourceResolver.PROPERTY_RESOURCE_SUPER_TYPE;
+import static
org.apache.sling.api.resource.ResourceResolver.PROPERTY_RESOURCE_TYPE;
+
+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 final String jakartaBaseRequestComponentPath =
"/content/exp-request/baseComponentJakarta";
+ private final String jakartaExtendedRequestComponentPath =
"/content/exp-request/extendedComponentJakarta";
+ private final String jakartaInterfaceRequestComponentPath =
"/content/exp-request/interfaceComponentJakarta";
+ private Calendar testDate;
+
+ private Format dateFormat =
FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZ",
TimeZone.getTimeZone("UTC"));
+
+ @Before
+ 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(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(PROPERTY_RESOURCE_TYPE, "sling/exp-request/base");
+ ResourceUtil.getOrCreateResource(adminResolver,
baseRequestComponentPath, properties, null, false);
+
+ properties.put(PROPERTY_RESOURCE_TYPE,
"sling/exp-request/baseJakarta");
+ ResourceUtil.getOrCreateResource(adminResolver,
jakartaBaseRequestComponentPath, properties, null, false);
+ properties.clear();
+
+ properties.put("sampleValue", "childTESTValue");
+ properties.put(PROPERTY_RESOURCE_TYPE, "sling/exp/child");
+ properties.put(PROPERTY_RESOURCE_SUPER_TYPE, "sling/exp/base");
+ ResourceUtil.getOrCreateResource(adminResolver,
childComponentPath, properties, null, false);
+ properties.clear();
+
+ properties.put("sampleValue", "extendedTESTValue");
+ properties.put(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(PROPERTY_RESOURCE_TYPE,
"sling/exp-request/extended");
+ ResourceUtil.getOrCreateResource(adminResolver,
extendedRequestComponentPath, properties, null, false);
+
+ properties.put(PROPERTY_RESOURCE_TYPE,
"sling/exp-request/extendedJakarta");
+ ResourceUtil.getOrCreateResource(
+ adminResolver, jakartaExtendedRequestComponentPath,
properties, null, false);
+ properties.clear();
+
+ properties.put("sampleValue", "interfaceTESTValue");
+ properties.put(PROPERTY_RESOURCE_TYPE, "sling/exp/interface");
+ ResourceUtil.getOrCreateResource(adminResolver,
interfaceComponentPath, properties, null, false);
+
+ properties.put(PROPERTY_RESOURCE_TYPE,
"sling/exp-request/interface");
+ ResourceUtil.getOrCreateResource(adminResolver,
interfaceRequestComponentPath, properties, null, false);
+
+ properties.put(PROPERTY_RESOURCE_TYPE,
"sling/exp-request/interfaceJakarta");
+ ResourceUtil.getOrCreateResource(
+ adminResolver, jakartaInterfaceRequestComponentPath,
properties, null, false);
+ properties.clear();
+
+ properties.put(PROPERTY_RESOURCE_TYPE, "sling/exp/doubled");
+ ResourceUtil.getOrCreateResource(adminResolver,
doubledComponentPath, properties, null, false);
+
+ adminResolver.commit();
+ }
+ }
+
+ @Test
+ 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",
Strings.CS.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",
Strings.CS.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",
Strings.CS.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
+ @Ignore("TODO: enable when problem with Jakarta Servlet API -> Javax
Servlet API is solved")
+ 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(
+ "String does not start with '{\"UPPER\":': '" +
stringOutput + "'",
+ 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 testRequestServlets_Jakarta() throws Exception {
+ try (ResourceResolver resolver =
rrFactory.getServiceResourceResolver(null); ) {
+ JakartaFakeResponse response = new JakartaFakeResponse();
+ slingRequestProcessor.processRequest(
+ new JakartaFakeRequest(jakartaBaseRequestComponentPath +
".model.json"), response, resolver);
+ String stringOutput = response.getStringWriter().toString();
+
+ Assert.assertTrue(
+ "String does not start with '{\"UPPER\":': '" +
stringOutput + "'",
+ 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(jakartaBaseRequestComponentPath,
obj.getString("id"));
+
+ response = new JakartaFakeResponse();
+ slingRequestProcessor.processRequest(
+ new JakartaFakeRequest(jakartaExtendedRequestComponentPath
+ ".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(jakartaExtendedRequestComponentPath,
obj.getString("id"));
+ Assert.assertEquals(dateFormat.format(testDate),
obj.getString("date"));
+
+ response = new JakartaFakeResponse();
+ slingRequestProcessor.processRequest(
+ new
JakartaFakeRequest(jakartaInterfaceRequestComponentPath + ".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(jakartaInterfaceRequestComponentPath,
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);
+ }
+}