Skip to content

Commit a5eb034

Browse files
Live Preview
1 parent 246caad commit a5eb034

File tree

7 files changed

+213
-99
lines changed

7 files changed

+213
-99
lines changed

src/main/java/com/contentstack/sdk/CSHttpConnection.java

Lines changed: 24 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,8 @@ private void getService(String requestUrl) throws IOException {
190190
if (response.isSuccessful()) {
191191
assert response.body() != null;
192192
responseJSON = new JSONObject(response.body().string());
193-
// LivePreviewAgent to validate If LivePreview Response is there for mapping
194193
if (this.config.livePreviewEntry != null && !this.config.livePreviewEntry.isEmpty()) {
195-
livePreviewAgent();
194+
handleJSONArray();
196195
}
197196
connectionRequest.onRequestFinished(CSHttpConnection.this);
198197
} else {
@@ -202,54 +201,32 @@ private void getService(String requestUrl) throws IOException {
202201

203202
}
204203

205-
private void livePreviewAgent() {
206-
if (!responseJSON.isEmpty() && responseJSON.has("entries")) {
207-
mapLPreviewToQuery(responseJSON.optJSONArray("entries"));
208-
}
209-
if (responseJSON.has("entry")) {
210-
mapLPreviewToEntry(responseJSON.optJSONObject("entry"), 0);
211-
}
212-
}
213204

214-
private void mapLPreviewToEntry(JSONObject entry, int idx) {
215-
if (entry.opt("uid").equals(this.config.livePreviewEntry.opt("uid"))) {
216-
filterToUpdate(entry, idx);
205+
void handleJSONArray() {
206+
JSONArray entries = new JSONArray();
207+
if (responseJSON.has("entries") && !responseJSON.optJSONArray("entries").isEmpty()) {
208+
entries = responseJSON.optJSONArray("entries");
217209
}
218-
}
219-
220-
// How to merge the JSONObject key value to another key?
221-
// JSONObject a = new JSONObject("{\"data\": [ {\"empId\": 1,\"deptId\":
222-
// 2},{\"empId\": 3,\"deptId\": 4}]}");
223-
// JSONObject b = new JSONObject("{\"data\": [ {\"empId\": 7,\"deptId\":
224-
// 8},{\"empId\": 9,\"deptId\": 10}]}");
225-
226-
// JSONArray jArr_A= a.getJSONArray("data");
227-
228-
// JSONArray jArr= new JSONArray();
229-
// for(int i=0;i<jArr_A.length();i++){
230-
// jArr.put(jArr_A.getJSONObject(i));
231-
// }
232-
233-
// jArr_A= b.getJSONArray("data");
234-
235-
// for(int i=0;i<jArr_A.length();i++){
236-
// jArr.put(jArr_A.getJSONObject(i));
237-
// }
238-
239-
// JSONObject mainJson = new JSONObject();
240-
// mainJson.put("data", jArr);
241-
242-
private void filterToUpdate(JSONObject entry, int idx) {
243-
JSONObject rec = responseJSON.optJSONArray("entries").getJSONObject(idx);
244-
if (rec.has("uid") && entry.opt("uid").equals(rec.opt("uid"))) {
245-
responseJSON.optJSONArray("entries").getJSONObject(idx).put(String.valueOf(entry), idx);
246-
// System.out.println();
247-
// TODO: Check again before commit.
210+
JSONArray finalEntries = entries;
211+
IntStream.range(0, entries.length()).forEach(idx -> {
212+
JSONObject objJSON = (JSONObject) finalEntries.get(idx);
213+
handleJSONObject(finalEntries, objJSON, idx);
214+
});
215+
}
216+
217+
void handleJSONObject(JSONArray arrayEntry, JSONObject jsonObj, int idx) {
218+
if (!jsonObj.isEmpty()) {
219+
if (jsonObj.has("uid") && jsonObj.opt("uid").equals(this.config.livePreviewEntry.opt("uid"))) {
220+
arrayEntry.put(idx, this.config.livePreviewEntry);
221+
} else {
222+
Iterator<String> unmachedKeys = jsonObj.keys();
223+
unmachedKeys.forEachRemaining(key -> {
224+
JSONObject jsonBYKey = (JSONObject) jsonObj.opt(key);
225+
handleJSONObject(arrayEntry, jsonBYKey, idx);
226+
});
227+
}
248228
}
249-
}
250-
251-
private void mapLPreviewToQuery(JSONArray entries) {
252-
IntStream.range(0, entries.length()).forEach(idx -> mapLPreviewToEntry((JSONObject) entries.get(idx), idx));
229+
responseJSON = new JSONObject().put("entries", arrayEntry);
253230
}
254231

255232
void setError(String errResp) {

src/main/java/com/contentstack/sdk/Contentstack.java

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
import java.util.Objects;
44

55
/**
6-
* The Content Delivery API is used to retrieve content from your Contentstack
7-
* account and deliver it to your web or mobile properties. If you are looking
8-
* for APIs to manage content, you should use the Content Management API
6+
* The Content Delivery API is used to retrieve content from your Contentstack account and deliver it to your web or
7+
* mobile properties. If you are looking for APIs to manage content, you should use the Content Management API
98
* <p>
10-
* Our APIs serve content via a powerful and robust content delivery network
11-
* (CDN). Multiple datacenters around the world store a cached copy of your
12-
* content. When a page request is made, the content is delivered to the user
13-
* from the nearest server. This greatly accelerates content delivery and
14-
* reduces latency.
9+
* Our APIs serve content via a powerful and robust content delivery network (CDN). Multiple datacenters around the
10+
* world store a cached copy of your content. When a page request is made, the content is delivered to the user from the
11+
* nearest server. This greatly accelerates content delivery and reduces latency.
1512
*/
1613
public class Contentstack {
1714

@@ -21,28 +18,30 @@ protected Contentstack() throws IllegalAccessException {
2118
}
2219

2320
/**
24-
* A stack is a space that stores the content of a project (a web or mobile
25-
* property). Within a stack, you can create content structures, content
26-
* entries, users, etc. related to the project. <br>
27-
* Authenticates the stack api key of your stack. <br>
28-
* Find Your Stack Credentials from Contentstack .
21+
* A stack is a space that stores the content of a project (a web or mobile property). Within a stack, you can
22+
* create content structures, content entries, users, etc. related to the project. <br> Authenticates the stack api
23+
* key of your stack. <br> Find Your Stack Credentials from Contentstack .
2924
*
30-
* @param stackApiKey The API Key is a unique key assigned to each stack.
31-
* @param deliveryToken The Delivery Token is a read-only credential that you
32-
* can create for different environments of your stack
33-
* @param environment the environment for the stack
25+
* @param stackApiKey
26+
* The API Key is a unique key assigned to each stack.
27+
* @param deliveryToken
28+
* The Delivery Token is a read-only credential that you can create for different environments of your
29+
* stack
30+
* @param environment
31+
* the environment for the stack
3432
* @return the stack
35-
* @throws IllegalAccessException the illegal access exception
33+
* @throws IllegalAccessException
34+
* the illegal access exception
35+
* <p>
36+
* <b>Example</b>
3637
*
37-
* <b>Example</b>
38-
*
39-
* <pre>
40-
* {
41-
* &#64;Code
42-
* Stack stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
43-
* }
38+
* <pre>
39+
* {
40+
* &#64;Code
41+
* Stack stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
42+
* }
4443
*
45-
* </pre>
44+
* </pre>
4645
*/
4746
public static Stack stack(String stackApiKey, String deliveryToken, String environment)
4847
throws IllegalAccessException {
@@ -52,21 +51,23 @@ public static Stack stack(String stackApiKey, String deliveryToken, String envir
5251
}
5352

5453
/**
55-
* A stack is a space that stores the content of a project (a web or mobile
56-
* property). Within a stack, you can create content structures, content
57-
* entries, users, etc. related to the project.
54+
* A stack is a space that stores the content of a project (a web or mobile property). Within a stack, you can
55+
* create content structures, content entries, users, etc. related to the project.
5856
*
59-
* @param stackApiKey The API Key is a unique key assigned to each stack.
60-
* @param deliveryToken The Delivery Token is a read-only credential that you
61-
* can create for different environments of your stack
62-
* @param environment the environment for the stack
63-
* @param config the config
57+
* @param stackApiKey
58+
* The API Key is a unique key assigned to each stack.
59+
* @param deliveryToken
60+
* The Delivery Token is a read-only credential that you can create for different environments of your
61+
* stack
62+
* @param environment
63+
* the environment for the stack
64+
* @param config
65+
* the config
6466
* @return the stack
65-
* @throws IllegalAccessException the illegal access exception <b>Example</b>
66-
*
67-
* { @Code Stack stack =
68-
* contentstack.Stack("apiKey", "deliveryToken",
69-
* "environment"); }
67+
* @throws IllegalAccessException
68+
* the illegal access exception <b>Example</b>
69+
* <p>
70+
* { @Code Stack stack = contentstack.Stack("apiKey", "deliveryToken", "environment"); }
7071
*/
7172
public static Stack stack(String stackApiKey, String deliveryToken, String environment, Config config)
7273
throws IllegalAccessException {

src/main/java/com/contentstack/sdk/Query.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,7 @@ private LinkedHashMap<String, Object> getUrlParams(JSONObject jsonMain) {
13421342
@Override
13431343
public void getResult(Object object, String controller) {
13441344
// It would not be called.
1345+
//System.out.println(object);
13451346
}
13461347

13471348
@Override

src/main/java/com/contentstack/sdk/Stack.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,10 @@ public void syncPaginationToken(@NotNull String paginationToken, SyncResultCallB
372372
* <br>
373373
* <b>Example :</b><br>
374374
* <pre class="prettyprint">
375-
* Stack stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
376-
* stack.syncToken("syncToken")
377-
* stack.syncToken(sync_token, new SyncResultCallBack() ){ }
378-
* </pre>
375+
* Stack stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
376+
* stack.syncToken("syncToken")
377+
* stack.syncToken(sync_token, new SyncResultCallBack() ){ }
378+
* </pre>
379379
*/
380380
public void syncToken(String syncToken, SyncResultCallBack syncCallBack) {
381381
this.sync(null);
@@ -477,10 +477,10 @@ public void syncLocale(String localeCode, SyncResultCallBack syncCallBack) {
477477
* <br>
478478
* <b>Example :</b><br>
479479
* <pre class="prettyprint">
480-
* Stack stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
481-
* stack.syncPublishType(PublishType)
482-
* stackInstance.syncPublishType(Stack.PublishType.entry_published, new SyncResultCallBack()) { }
483-
* </pre>
480+
* Stack stack = contentstack.Stack("apiKey", "deliveryToken", "environment");
481+
* stack.syncPublishType(PublishType)
482+
* stackInstance.syncPublishType(Stack.PublishType.entry_published, new SyncResultCallBack()) { }
483+
* </pre>
484484
*/
485485
public void syncPublishType(PublishType publishType, SyncResultCallBack syncCallBack) {
486486
this.sync(null);
@@ -508,9 +508,8 @@ public void syncPublishType(PublishType publishType, SyncResultCallBack syncCall
508508
* <br>
509509
* <b>Example :</b><br>
510510
*/
511-
public void sync(
512-
String contentType, Date fromDate, String localeCode, PublishType publishType, SyncResultCallBack
513-
syncCallBack) {
511+
public void sync(String contentType, Date fromDate, String localeCode,
512+
PublishType publishType, SyncResultCallBack syncCallBack) {
514513
String newDate = convertUTCToISO(fromDate);
515514
this.sync(null);
516515
syncParams.put("start_from", newDate);
@@ -538,8 +537,8 @@ private void fetchContentTypes(String urlString, JSONObject
538537
}
539538
}
540539

541-
private void fetchFromNetwork(String urlString, JSONObject urlQueries, HashMap<String, Object> headers,
542-
SyncResultCallBack callback) {
540+
private void fetchFromNetwork(String urlString, JSONObject urlQueries,
541+
HashMap<String, Object> headers, SyncResultCallBack callback) {
543542
if (callback != null) {
544543
HashMap<String, Object> urlParams = getUrlParams(urlQueries);
545544
String requestInfo = REQUEST_CONTROLLER.SYNC.toString();
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.contentstack.sdk;
2+
3+
import com.google.gson.JsonElement;
4+
import com.google.gson.JsonObject;
5+
import com.google.gson.JsonParser;
6+
7+
import java.util.Map;
8+
9+
// SuperEntry is used as the common class that caould be consumed by Entry and Query
10+
public class SuperEntry {
11+
12+
13+
/**
14+
* Merge "source" into "target". If fields have equal name, merge them recursively. Null values in source will
15+
* remove the field from the target. Override target values with source values Keys not supplied in source will
16+
* remain unchanged in target
17+
*
18+
* @return the merged object (target).
19+
*/
20+
public static JsonObject deepMerge(JsonObject source, JsonObject target) {
21+
22+
for (Map.Entry<String, JsonElement> sourceEntry : source.entrySet()) {
23+
String key = sourceEntry.getKey();
24+
JsonElement value = sourceEntry.getValue();
25+
if (!target.has(key)) {
26+
//target does not have the same key, so perhaps it should be added to target
27+
if (!value.isJsonNull()) //well, only add if the source value is not null
28+
target.add(key, value);
29+
} else {
30+
if (!value.isJsonNull()) {
31+
if (value.isJsonObject()) {
32+
//source value is json object, start deep merge
33+
deepMerge(value.getAsJsonObject(), target.get(key).getAsJsonObject());
34+
} else {
35+
target.add(key, value);
36+
}
37+
} else {
38+
target.remove(key);
39+
}
40+
}
41+
}
42+
return target;
43+
}
44+
45+
46+
/**
47+
* simple test
48+
*/
49+
public static void main(String[] args) {
50+
JsonParser parser = new JsonParser();
51+
JsonObject sourse = parser.parse("{offer: {issue1: null, issue2: null}, accept: true, reject: null}").getAsJsonObject();
52+
JsonObject target = parser.parse("{offer: {issue2: value2}, reject: false}").getAsJsonObject();
53+
System.out.println(deepMerge(sourse, target));
54+
}
55+
56+
57+
}

src/test/java/com/contentstack/sdk/TestLivePreview.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,23 @@ void testCompleteLivePreviewInQuery() throws Exception {
156156
Assertions.assertNotNull(entry);
157157
}
158158

159+
@Test()
160+
void testUpdatedLivePreviewQuery() throws Exception {
161+
Config livePreviewEnablerConfig = new Config().enableLivePreview(true)
162+
.setLivePreviewHost("api.contentstack.io")
163+
.setManagementToken("***REMOVED***");
164+
Stack stack = Contentstack.stack("***REMOVED***", "***REMOVED***", "development", livePreviewEnablerConfig);
165+
HashMap<String, String> hashMap = new HashMap<>();
166+
hashMap.put("content_type_uid", "bugfixes");
167+
hashMap.put("entry_uid", "blt009591baa60f3f3b");
168+
stack.livePreviewQuery(hashMap);
169+
Query entry = stack.contentType("bugfixes").query();
170+
entry.find(new QueryResultsCallBack() {
171+
@Override
172+
public void onCompletion(ResponseType responseType, QueryResult queryresult, Error error) {
173+
Assertions.assertNotNull(entry);
174+
}
175+
});
176+
Assertions.assertNotNull(entry);
177+
}
159178
}

0 commit comments

Comments
 (0)