Skip to content

Commit 447060c

Browse files
author
zhourenjian@gmail.com
committed
Add supports of object serialization and deserialization
Add supports of serializing to JSON strings and deserializing from properties Add supports of pipe sequence
1 parent bbd9ff1 commit 447060c

8 files changed

Lines changed: 1102 additions & 70 deletions

File tree

sources/net.sf.j2s.ajax/ajaxpipe/net/sf/j2s/ajax/SimplePipeHelper.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,12 @@ public static void pipeIn(String key, SimpleSerializable[] ss) {
207207
if (s instanceof ISimpleCacheable) {
208208
ISimpleCacheable c = (ISimpleCacheable) s;
209209
if (c.isCached()) {
210-
// already buffered
210+
// in buffer and not sent yet
211211
continue;
212212
} else {
213213
int idx = list.indexOf(s);
214-
if (idx != -1) {
215-
// same object but may be with updated properties!
214+
if (idx != -1 && idx > pipe.getLastBufferedIndex()) {
215+
// same object but with updated properties maybe!
216216
SimpleSerializable existed = list.get(idx);
217217
if (existed instanceof ISimpleCacheable) {
218218
ISimpleCacheable ec = (ISimpleCacheable) existed;

sources/net.sf.j2s.ajax/ajaxpipe/net/sf/j2s/ajax/SimplePipeRequest.java

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ public static interface IHttpPipeRequestFactory extends IHttpRequestFactory {
108108
* Query key for pipe: pipernd
109109
*/
110110
public static final String FORM_PIPE_RANDOM = "r"; // "pipernd";
111+
112+
/**
113+
* Query key for pipe: pipeseq
114+
*/
115+
public static final String FORM_PIPE_SEQUENCE = "s"; // "pipeseq";
111116

112117
static final int PIPE_KEY_LENGTH = 6;
113118

@@ -160,11 +165,12 @@ public static void switchToContinuumMode() {
160165
* @param pipeRequestType
161166
* @return request data for both GET and POST request.
162167
*/
163-
protected static String constructRequest(String pipeKey, String pipeRequestType) {
168+
protected static String constructRequest(String pipeKey, String pipeRequestType, long pipeSequence) {
164169
reqCount++;
165170
return FORM_PIPE_KEY + "=" + pipeKey + "&"
166-
+ FORM_PIPE_TYPE + "=" + pipeRequestType
167-
+ "&" + FORM_PIPE_RANDOM + "=" + reqCount;
171+
+ FORM_PIPE_TYPE + "=" + pipeRequestType + "&"
172+
+ FORM_PIPE_SEQUENCE + "=" + pipeSequence + "&"
173+
+ FORM_PIPE_RANDOM + "=" + reqCount;
168174
}
169175

170176
protected static void sendRequest(HttpRequest request, String method, String url,
@@ -213,7 +219,7 @@ public void run() {
213219
@J2SIgnore
214220
static void keepPipeLive(final SimplePipeRunnable runnable) {
215221
runnable.updateStatus(true);
216-
if (getRequstMode() != MODE_LOCAL_JAVA_THREAD) {
222+
if (getRequstMode() != MODE_LOCAL_JAVA_THREAD && getPipeMode() == MODE_PIPE_QUERY) {
217223
return;
218224
}
219225
//*
@@ -227,7 +233,7 @@ public void run() {
227233
while (interval > 0) {
228234
try {
229235
Thread.sleep(Math.min(interval, 1000));
230-
interval -= 1000;
236+
interval -= 1000 + (runnable.pipeSequence - runnable.notifySequence) * 1000;
231237
} catch (InterruptedException e) {
232238
//e.printStackTrace();
233239
}
@@ -257,15 +263,18 @@ public void run() {
257263
}
258264
} else {
259265
SimplePipeRunnable r = SimplePipeHelper.getPipe(runnable.pipeKey);
260-
if (r != null) {
266+
if (r != null && r.pipeSequence != r.notifySequence) {
261267
HttpRequest request = getRequest();
262268
String pipeKey = runnable.pipeKey;
263269
String pipeMethod = runnable.getPipeMethod();
264270
String pipeURL = runnable.getPipeURL();
265-
266-
String pipeRequestData = constructRequest(pipeKey, PIPE_TYPE_NOTIFY);
271+
long sequence = runnable.pipeSequence;
272+
String pipeRequestData = constructRequest(pipeKey, PIPE_TYPE_NOTIFY, sequence);
267273
sendRequest(request, pipeMethod, pipeURL, pipeRequestData, false);
268274
String response = request.getResponseText();
275+
if (response != null && runnable.notifySequence < sequence) {
276+
runnable.notifySequence = sequence;
277+
}
269278
if (response != null && response.indexOf("\"" + PIPE_STATUS_LOST + "\"") != -1) {
270279
runnable.pipeAlive = false;
271280
runnable.pipeLost();
@@ -491,9 +500,9 @@ public void onLoaded() {
491500
html += " net.sf.j2s.ajax.SimplePipeRequest.parseReceived (string);\r\n";
492501
html += " };\r\n";
493502
html += "};\r\n";
494-
html += "window[\"$p1p3b$\"] = function (key, result) {\r\n";
503+
html += "window[\"$p1p3b$\"] = function (key, result, sequence) {\r\n";
495504
html += " with (window.parent) {\r\n";
496-
html += " net.sf.j2s.ajax.SimplePipeRequest.pipeNotifyCallBack (key, result);\r\n";
505+
html += " net.sf.j2s.ajax.SimplePipeRequest.pipeNotifyCallBack (key, result, sequence);\r\n";
497506
html += " };\r\n";
498507
html += "};\r\n";
499508
html += "</scr" + "ipt></head><body><script type=\"text/javascript\">\r\n";
@@ -582,7 +591,7 @@ static void pipeScript(SimplePipeRunnable runnable) { // xss
582591
// only for JavaScript
583592
String url = runnable.getPipeURL();
584593
String requestURL = url + (url.indexOf('?') != -1 ? "&" : "?")
585-
+ constructRequest(runnable.pipeKey, PIPE_TYPE_XSS);
594+
+ constructRequest(runnable.pipeKey, PIPE_TYPE_XSS, runnable.pipeSequence);
586595
/**
587596
* @j2sNative
588597
* net.sf.j2s.ajax.SimplePipeRequest.pipeScriptMap[requestURL] = runnable;
@@ -627,7 +636,7 @@ static void pipeScript(SimplePipeRunnable runnable) { // xss
627636
ifr.style.display = "none";
628637
var url = runnable.getPipeURL();
629638
var src = url + (url.indexOf('?') != -1 ? "&" : "?")
630-
+ spr.constructRequest(pipeKey, spr.PIPE_TYPE_SUBDOMAIN_QUERY)
639+
+ spr.constructRequest(pipeKey, spr.PIPE_TYPE_SUBDOMAIN_QUERY, runnable.pipeSequence)
631640
+ "&" + spr.FORM_PIPE_DOMAIN + "=" + domain;
632641
ifr.id = "pipe-" + pipeKey;
633642
ifr.src = src;
@@ -638,14 +647,17 @@ static void pipeScript(SimplePipeRunnable runnable) { // xss
638647
static void pipeNotify(SimplePipeRunnable runnable) { // notifier
639648
String url = runnable.getPipeURL();
640649
loadPipeScript(url + (url.indexOf('?') != -1 ? "&" : "?")
641-
+ constructRequest(runnable.pipeKey, PIPE_TYPE_NOTIFY));
650+
+ constructRequest(runnable.pipeKey, PIPE_TYPE_NOTIFY, runnable.pipeSequence));
642651
// only for JavaScript
643652
}
644653

645-
static void pipeNotifyCallBack(String key, String result) {
646-
if (PIPE_STATUS_LOST.equals(result)) {
647-
SimplePipeRunnable pipe = SimplePipeHelper.getPipe(key);
648-
if (pipe != null) {
654+
static void pipeNotifyCallBack(String key, String result, long sequence) {
655+
SimplePipeRunnable pipe = SimplePipeHelper.getPipe(key);
656+
if (pipe != null) {
657+
if (pipe.notifySequence < sequence) {
658+
pipe.notifySequence = sequence;
659+
}
660+
if (PIPE_STATUS_LOST.equals(result)) {
649661
pipe.pipeAlive = false;
650662
pipe.pipeLost();
651663
SimplePipeHelper.removePipe(key);
@@ -699,7 +711,7 @@ public void onLoaded() {
699711

700712
});
701713

702-
String pipeRequestData = constructRequest(pipeKey, PIPE_TYPE_QUERY);
714+
String pipeRequestData = constructRequest(pipeKey, PIPE_TYPE_QUERY, runnable.pipeSequence);
703715
boolean async = false;
704716
/**
705717
* In JavaScript such queries are not wrapped inside Thread, so asynchronous mode is required!
@@ -767,7 +779,7 @@ protected IXHRReceiving initializeReceivingMonitor() {
767779
window["xss.domain.enabled"] = true;
768780
}
769781
ifr.src = url + (url.indexOf('?') != -1 ? "&" : "?")
770-
+ spr.constructRequest(pipeKey, spr.PIPE_TYPE_SCRIPT)
782+
+ spr.constructRequest(pipeKey, spr.PIPE_TYPE_SCRIPT, runnable.pipeSequence)
771783
+ (subdomain == null ? ""
772784
: "&" + spr.FORM_PIPE_DOMAIN + "=" + subdomain);
773785
document.body.appendChild (ifr);
@@ -781,6 +793,10 @@ protected IXHRReceiving initializeReceivingMonitor() {
781793
var runnable = sph.getPipe(key);
782794
if (runnable != null) {
783795
var spr = net.sf.j2s.ajax.SimplePipeRequest;
796+
if (runnable.pipeSequence == runnable.notifySequence) {
797+
window.setTimeout (arguments.callee, spr.pipeLiveNotifyInterval);
798+
return;
799+
}
784800
var now = new Date ().getTime ();
785801
var last = runnable.lastPipeDataReceived;
786802
if (last <= 0) {
@@ -858,7 +874,7 @@ public void onLoaded() { // on case that no destroy event is sent to client
858874
String pipeMethod = runnable.getPipeMethod();
859875
String pipeURL = runnable.getPipeURL();
860876

861-
String pipeRequestData = constructRequest(pipeKey, PIPE_TYPE_CONTINUUM);
877+
String pipeRequestData = constructRequest(pipeKey, PIPE_TYPE_CONTINUUM, runnable.pipeSequence);
862878
sendRequest(pipeRequest, pipeMethod, pipeURL, pipeRequestData, true);
863879
}
864880

@@ -990,7 +1006,14 @@ public static String parseReceived(final String string) {
9901006
if (runnable != null) { // should always satisfy this condition
9911007
runnable.lastPipeDataReceived = System.currentTimeMillis();
9921008
if (ss != SimpleSerializable.UNKNOWN) {
993-
runnable.deal(ss);
1009+
if (ss instanceof SimplePipeSequence) {
1010+
long sequence = ((SimplePipeSequence) ss).sequence;
1011+
if (sequence > runnable.pipeSequence) {
1012+
runnable.pipeSequence = sequence;
1013+
}
1014+
} else {
1015+
runnable.deal(ss);
1016+
}
9941017
}
9951018
}
9961019

@@ -1344,7 +1367,7 @@ public void run() {
13441367
method = runnable.getPipeMethod ();
13451368
url = runnable.getPipeURL ();
13461369
var spr = net.sf.j2s.ajax.SimplePipeRequest;
1347-
data = spr.constructRequest(key, spr.PIPE_TYPE_QUERY);
1370+
data = spr.constructRequest(key, spr.PIPE_TYPE_QUERY, runnable.pipeSequence);
13481371
} catch (e) {
13491372
}
13501373
}
@@ -1357,7 +1380,7 @@ public void run() {
13571380
method = runnable.getPipeMethod ();
13581381
url = runnable.getPipeURL ();
13591382
var spr = net.sf.j2s.ajax.SimplePipeRequest;
1360-
data = spr.constructRequest(key, spr.PIPE_TYPE_QUERY);
1383+
data = spr.constructRequest(key, spr.PIPE_TYPE_QUERY, runnable.pipeSequence);
13611384
} catch (e) {
13621385
}
13631386
}

sources/net.sf.j2s.ajax/ajaxpipe/net/sf/j2s/ajax/SimplePipeRunnable.java

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import net.sf.j2s.ajax.SimpleRPCRunnable;
1919
import net.sf.j2s.ajax.SimpleSerializable;
2020
import net.sf.j2s.annotation.J2SIgnore;
21+
import net.sf.j2s.annotation.J2SNative;
2122

2223
/**
2324
*
@@ -55,14 +56,59 @@ public abstract class SimplePipeRunnable extends SimpleRPCRunnable {
5556
@J2SIgnore
5657
long lastHash;
5758

59+
long pipeSequence = 1;
60+
61+
long notifySequence = 1;
62+
63+
@J2SIgnore
64+
int sequenceIndex; // Index of last SimplePipeSequence in pipeData
65+
66+
@J2SIgnore
67+
int bufferedIndex; // Index of last buffered object in pipeData
68+
5869
@J2SIgnore
5970
List<SimpleSerializable> pipeData;
6071

6172
@J2SIgnore
6273
public List<SimpleSerializable> getPipeData() {
6374
return pipeData;
6475
}
76+
77+
@J2SIgnore
78+
public void setLastPipeSequenceIndex(int index) {
79+
sequenceIndex = index;
80+
}
6581

82+
@J2SIgnore
83+
public int getLastPipeSequenceIndex() {
84+
return sequenceIndex;
85+
}
86+
87+
@J2SIgnore
88+
public int getLastBufferedIndex() {
89+
return bufferedIndex;
90+
}
91+
92+
@J2SIgnore
93+
public void setLastBufferedIndex(int index) {
94+
bufferedIndex = index;
95+
}
96+
97+
@J2SIgnore
98+
public long getSequence() {
99+
return pipeSequence;
100+
}
101+
102+
@J2SIgnore
103+
public long increaseSequence() {
104+
return ++pipeSequence;
105+
}
106+
107+
@J2SIgnore
108+
public void setSequence(long sequence) {
109+
pipeSequence = sequence;
110+
}
111+
66112
@J2SIgnore
67113
public void setPipeHelper(SimplePipeHelper.IPipeThrough helper) {
68114
pipeManaged = true;
@@ -125,7 +171,7 @@ public void ajaxOut() {
125171
*
126172
* For server side only.
127173
*/
128-
@J2SIgnore
174+
@J2SNative("")
129175
protected void pipeClearData() {
130176
if (pipeData != null) {
131177
pipeData = null;
@@ -145,39 +191,27 @@ protected boolean hasPipeData() {
145191
}
146192

147193
@J2SIgnore
148-
protected void pipeCloneData(SimplePipeRunnable anotherPipe, SimpleFilter filter) {
194+
protected void pipeCloneData(SimplePipeRunnable anotherPipe, SimpleFilter filter, boolean clearOriginalData) {
149195
if (anotherPipe == this) {
150196
return;
151197
}
152198
if (anotherPipe != null && anotherPipe.pipeData != null && anotherPipe.pipeData.size() > 0) {
153199
if (pipeData == null) {
154200
List<SimpleSerializable> data = new Vector<SimpleSerializable>(anotherPipe.pipeData.size());
201+
pipeData = data;
202+
}
203+
synchronized (pipeData) {
155204
synchronized (anotherPipe.pipeData) {
156-
if (filter == null) {
157-
data.addAll(anotherPipe.pipeData);
158-
} else {
159-
for (Iterator<SimpleSerializable> itr = anotherPipe.pipeData.iterator(); itr.hasNext();) {
160-
SimpleSerializable event = (SimpleSerializable) itr.next();
161-
if (filter.accept(event.getClass().getName())) {
162-
data.add(event);
163-
}
205+
for (Iterator<SimpleSerializable> itr = anotherPipe.pipeData.iterator(); itr.hasNext();) {
206+
SimpleSerializable event = (SimpleSerializable) itr.next();
207+
if (event instanceof SimplePipeSequence) {
208+
continue;
164209
}
165-
}
166-
}
167-
pipeData = data;
168-
} else {
169-
synchronized (pipeData) {
170-
synchronized (anotherPipe.pipeData) {
171-
if (filter == null) {
172-
pipeData.addAll(anotherPipe.pipeData);
173-
} else {
174-
for (Iterator<SimpleSerializable> itr = anotherPipe.pipeData.iterator(); itr.hasNext();) {
175-
SimpleSerializable event = (SimpleSerializable) itr.next();
176-
if (filter.accept(event.getClass().getName())) {
177-
pipeData.add(event);
178-
}
179-
}
210+
if (filter != null && filter.accept(event.getClass().getName())) {
211+
pipeData.add(event);
180212
}
213+
}
214+
if (clearOriginalData) {
181215
anotherPipe.pipeData.clear();
182216
}
183217
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package net.sf.j2s.ajax;
2+
3+
public final class SimplePipeSequence extends SimpleSerializable {
4+
5+
public long sequence;
6+
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package net.sf.j2s.ajax;
2+
3+
public interface ISimpleConstant {
4+
5+
}

sources/net.sf.j2s.ajax/ajaxrpc/net/sf/j2s/ajax/SimpleRPCUtils.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public static String[] compareDiffs(SimpleRPCRunnable runnable1, SimpleRPCRunnab
7373
}
7474
} else if (field2 == null) { // field1 != null
7575
diffSet.add(name);
76-
} else if (field1.getClass().getName().startsWith("[")) {
76+
} else if (field1.getClass().isArray()) {
7777
Class<?> type = field.getType();
7878
if (type == float[].class) {
7979
if (!Arrays.equals((float[]) field1, (float[]) field2)) {
@@ -111,11 +111,15 @@ public static String[] compareDiffs(SimpleRPCRunnable runnable1, SimpleRPCRunnab
111111
if (!Arrays.equals((String[]) field1, (String[]) field2)) {
112112
diffSet.add(name);
113113
}
114+
} else if (SimpleSerializable.isSubclassOf(type, SimpleSerializable[].class)) {
115+
diffSet.add(name);
114116
} else if (type == Object[].class) {
115117
if (!Arrays.equals((Object[]) field1, (Object[]) field2)) {
116118
diffSet.add(name);
117119
}
118120
}
121+
} else if (SimpleSerializable.isSubclassOf(field.getType(), SimpleSerializable.class)) {
122+
diffSet.add(name);
119123
} else if (!field1.equals(field2)) {
120124
diffSet.add(name);
121125
}

0 commit comments

Comments
 (0)