diff --git a/src/main/java/com/contentstack/cms/stack/Entry.java b/src/main/java/com/contentstack/cms/stack/Entry.java index 8fb6d88..818229a 100644 --- a/src/main/java/com/contentstack/cms/stack/Entry.java +++ b/src/main/java/com/contentstack/cms/stack/Entry.java @@ -189,6 +189,11 @@ public Call find() { return this.service.fetch(this.headers, this.contentTypeUid, this.params); } + public Call findAsPojo() { + validateCT(); + return this.service.fetchPojo(this.headers, this.contentTypeUid, this.params); + } + /** * The Get a single entry request fetches a particular entry of a content * type. @@ -214,6 +219,11 @@ public Call fetch() { validateEntry(); return this.service.single(headers, this.contentTypeUid, this.entryUid, this.params); } + public Call fetchAsPojo() { + validateCT(); + validateEntry(); + return this.service.singlePojo(headers, this.contentTypeUid, this.entryUid, this.params); + } /** * The Create an entry call creates a new entry for the selected content type. diff --git a/src/main/java/com/contentstack/cms/stack/EntryListResponse.java b/src/main/java/com/contentstack/cms/stack/EntryListResponse.java new file mode 100644 index 0000000..d41c5e3 --- /dev/null +++ b/src/main/java/com/contentstack/cms/stack/EntryListResponse.java @@ -0,0 +1,46 @@ +package com.contentstack.cms.stack; +import com.google.gson.annotations.SerializedName; +import com.google.gson.JsonObject; +import com.google.gson.JsonElement; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.util.*; + +public class EntryListResponse { + + @SerializedName("entries") + private List rawEntries; + + private transient List entries; + + public List getEntries() { + if (entries == null && rawEntries != null) { + Gson gson = new Gson(); + entries = new ArrayList<>(); + + for (JsonObject entryJson : rawEntries) { + EntryPojo entryPojo = gson.fromJson(entryJson, EntryPojo.class); + // Map dynamic fields + Map fields = new LinkedHashMap<>(); + for (Map.Entry field : entryJson.entrySet()) { + String key = field.getKey(); + if (!EntryPojo.SYSTEM_FIELDS.contains(key)) { + fields.put(key, gson.fromJson(field.getValue(), Object.class)); + } + } + entryPojo.setFields(fields); + entries.add(entryPojo); + } + } + return entries; + } + + public List getRawJson() { + return rawEntries; + } + + @Override + public String toString() { + return new GsonBuilder().setPrettyPrinting().create().toJson(this); + } +} diff --git a/src/main/java/com/contentstack/cms/stack/EntryPojo.java b/src/main/java/com/contentstack/cms/stack/EntryPojo.java new file mode 100644 index 0000000..9e97a29 --- /dev/null +++ b/src/main/java/com/contentstack/cms/stack/EntryPojo.java @@ -0,0 +1,52 @@ +package com.contentstack.cms.stack; +import java.util.Map; +import java.util.Set; +import java.util.HashSet; +import java.util.Arrays; +import com.google.gson.annotations.SerializedName; + +public class EntryPojo { + + @SerializedName("title") + public String title; + + @SerializedName("uid") + public String uid; + + @SerializedName("_version") + public int version; + + @SerializedName("locale") + public String locale; + + // Additional fields captured dynamically from content type schema + protected Map fields; + + public Map getFields() { + return fields; + } + + public void setFields(Map fields) { + this.fields = fields; + } + + public String getStringField(String key) { + Object value = fields.get(key); + return value != null ? value.toString() : null; + } + + public Map getJsonObjectField(String key) { + Object value = fields.get(key); + if (value instanceof Map) { + return (Map) value; + } + return null; + } + // Define system fields to exclude from dynamic mapping + public static final Set SYSTEM_FIELDS = new HashSet<>(Arrays.asList( + "title","uid", "_version", "locale", "tags", "ACL", "created_by", "updated_by", + "created_at", "updated_at", "_in_progress" + )); +} + + diff --git a/src/main/java/com/contentstack/cms/stack/EntryResponse.java b/src/main/java/com/contentstack/cms/stack/EntryResponse.java new file mode 100644 index 0000000..c9acc5c --- /dev/null +++ b/src/main/java/com/contentstack/cms/stack/EntryResponse.java @@ -0,0 +1,44 @@ +package com.contentstack.cms.stack; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class EntryResponse { + + @SerializedName("entry") + private JsonObject entryJson; + + private EntryPojo entryPojo; + + public EntryPojo getEntryPojo() { + if (entryPojo == null && entryJson != null) { + Gson gson = new Gson(); + // Deserialize system fields automatically + entryPojo = gson.fromJson(entryJson, EntryPojo.class); + // Manually extract and map only non-system (dynamic) fields + Map fields = new LinkedHashMap<>(); + for (Map.Entry entry : entryJson.entrySet()) { + String key = entry.getKey(); + if (!EntryPojo.SYSTEM_FIELDS.contains(key)) { + fields.put(key, gson.fromJson(entry.getValue(), Object.class)); + } + } + entryPojo.setFields(fields); + } + return entryPojo; + } + + public JsonObject getRawJson() { + return entryJson; + } + + @Override + public String toString() { + return new GsonBuilder().setPrettyPrinting().create().toJson(this); + } +} diff --git a/src/main/java/com/contentstack/cms/stack/EntryService.java b/src/main/java/com/contentstack/cms/stack/EntryService.java index 83f54d8..8c5c82f 100644 --- a/src/main/java/com/contentstack/cms/stack/EntryService.java +++ b/src/main/java/com/contentstack/cms/stack/EntryService.java @@ -16,6 +16,12 @@ Call fetch( @Path("content_type_uid") String contentTypeUid, @QueryMap(encoded = true) Map queryParameter); + @GET("content_types/{content_type_uid}/entries") + Call fetchPojo( + @HeaderMap Map headers, + @Path("content_type_uid") String contentTypeUid, + @QueryMap(encoded = true) Map queryParameter); + @Headers("Content-Type: application/json") @GET("content_types/{content_type_uid}/entries/{entry_uid}") Call single( @@ -24,6 +30,14 @@ Call single( @Path("entry_uid") String entryUid, @QueryMap(encoded = true) Map queryParameter); + @Headers("Content-Type: application/json") + @GET("content_types/{content_type_uid}/entries/{entry_uid}") + Call singlePojo( + @HeaderMap Map headers, + @Path("content_type_uid") String contentTypeUid, + @Path("entry_uid") String entryUid, + @QueryMap(encoded = true) Map queryParameter); + @Headers("Content-Type: application/json") @POST("content_types/{content_type_uid}/entries") Call create( diff --git a/src/test/java/com/contentstack/cms/stack/EntryFieldsAPITest.java b/src/test/java/com/contentstack/cms/stack/EntryFieldsAPITest.java index 3879ba7..c8bbedb 100644 --- a/src/test/java/com/contentstack/cms/stack/EntryFieldsAPITest.java +++ b/src/test/java/com/contentstack/cms/stack/EntryFieldsAPITest.java @@ -13,6 +13,7 @@ import retrofit2.Response; import java.io.IOException; +import java.util.List; import org.json.simple.JSONArray; import org.json.simple.parser.ParseException; @@ -551,4 +552,42 @@ void testPublishRequest_RejectRequest() throws ParseException { Assertions.assertTrue(request.headers().names().contains("authorization")); } + @Test + void testEntryPojo() throws IOException { + Request request = contentType.entry(API_KEY).fetchAsPojo().request(); + Assertions.assertEquals(3, request.headers().names().size()); + Assertions.assertEquals("GET", request.method()); + Assertions.assertTrue(request.url().isHttps()); + Assertions.assertEquals("api.contentstack.io", request.url().host()); + Assertions.assertEquals(5, request.url().pathSegments().size()); + Assertions.assertEquals("v3", request.url().pathSegments().get(0)); + Assertions.assertEquals("content_types", request.url().pathSegments().get(1)); + Assertions.assertEquals("test", request.url().pathSegments().get(2)); + Assertions.assertEquals("entries", request.url().pathSegments().get(3)); + Assertions.assertNull(request.url().encodedQuery()); + Assertions.assertEquals( + String.format("https://api.contentstack.io/v3/content_types/test/entries/"+ TestClient.API_KEY), + request.url().toString()); + } + @Test + void testEntryPojoList() throws IOException { + entry.addParam("include_count", true); + entry.addParam("limit", 10); + Request request = entry.findAsPojo().request(); + Assertions.assertEquals(_COUNT, request.headers().names().size()); + Assertions.assertEquals("GET", request.method()); + Assertions.assertTrue(request.url().isHttps()); + Assertions.assertEquals("api.contentstack.io", request.url().host()); + Assertions.assertEquals(4, request.url().pathSegments().size()); + Assertions.assertEquals("v3", request.url().pathSegments().get(0)); + Assertions.assertEquals("content_types", request.url().pathSegments().get(1)); + Assertions.assertEquals("test", request.url().pathSegments().get(2)); + Assertions.assertEquals("entries", request.url().pathSegments().get(3)); + Assertions.assertNotNull(request.url().encodedQuery()); + Assertions.assertEquals("limit=10&include_count=true", request.url().query().toString()); + Assertions.assertEquals( + String.format("https://api.contentstack.io/v3/content_types/test/entries?limit=10&include_count=true"), + request.url().toString()); + } + }