From df647d0858a07e41ccfc350a5dab4225e5711a9d Mon Sep 17 00:00:00 2001 From: Mover Date: Sat, 4 Jun 2016 13:47:39 +0800 Subject: [PATCH 01/16] Update smalltalk.java --- src/tinystruct/examples/smalltalk.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tinystruct/examples/smalltalk.java b/src/tinystruct/examples/smalltalk.java index 9d0a7b4..a473ffc 100644 --- a/src/tinystruct/examples/smalltalk.java +++ b/src/tinystruct/examples/smalltalk.java @@ -151,7 +151,7 @@ public String command() { final Object meetingCode = request.getSession().getAttribute("meeting_code"); final String sessionId = request.getSession().getId(); - if ( meetingCode != null && sessions.get(meetingCode).contains(sessionId)) { + if ( meetingCode != null && sessions.get(meetingCode) != null && sessions.get(meetingCode).contains(sessionId)) { if (request.getSession().getAttribute("user") == null) { return "{ \"error\": \"missing user\" }"; } From 03e98c763c03fb23d0822f42d18236d05d6cc752 Mon Sep 17 00:00:00 2001 From: "James M. Zhou" Date: Tue, 23 May 2017 03:51:19 -0400 Subject: [PATCH 02/16] It's unnecessary to wait for messages. --- src/tinystruct/examples/talk.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/tinystruct/examples/talk.java b/src/tinystruct/examples/talk.java index e6c3aa9..2086085 100644 --- a/src/tinystruct/examples/talk.java +++ b/src/tinystruct/examples/talk.java @@ -25,7 +25,7 @@ public class talk extends AbstractApplication { - private static final long TIMEOUT = 1; + private static final long TIMEOUT = 10; private static final int DEFAULT_POOL_SIZE = 3; protected static final int DEFAULT_MESSAGE_POOL_SIZE = 10; protected final Map> meetings = new ConcurrentHashMap>(); @@ -107,13 +107,7 @@ public final String save(final Object meetingCode, final Builder builder) { @Override public void run() { Builder message; - do { - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } while(talk.this.meetings.get(meetingCode) == null || (message = talk.this.meetings.get(meetingCode).poll()) == null); + if (talk.this.meetings.get(meetingCode) == null || (message = talk.this.meetings.get(meetingCode).poll()) == null) return; talk.this.copy(meetingCode, message); } }); From 52093bb75916be90fca1f0543d430edf5b43b78c Mon Sep 17 00:00:00 2001 From: m0ver Date: Tue, 23 May 2017 23:42:10 +0800 Subject: [PATCH 03/16] Use newSingleThreadExecutor to avoid "unable to create new native thread" issue. --- src/tinystruct/examples/talk.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tinystruct/examples/talk.java b/src/tinystruct/examples/talk.java index 2086085..56ced89 100644 --- a/src/tinystruct/examples/talk.java +++ b/src/tinystruct/examples/talk.java @@ -26,7 +26,6 @@ public class talk extends AbstractApplication { private static final long TIMEOUT = 10; - private static final int DEFAULT_POOL_SIZE = 3; protected static final int DEFAULT_MESSAGE_POOL_SIZE = 10; protected final Map> meetings = new ConcurrentHashMap>(); protected final Map> list = new ConcurrentHashMap>(); @@ -115,7 +114,7 @@ public void run() { } private ExecutorService getService() { - return this.service!=null? this.service : Executors.newFixedThreadPool(DEFAULT_POOL_SIZE); + return this.service!=null? this.service : Executors.newSingleThreadExecutor(); } /** From 54798cedf7b5cc77e1bc9fe7e10574fd695c78c4 Mon Sep 17 00:00:00 2001 From: "James M. Zhou" Date: Fri, 26 May 2017 01:46:10 -0400 Subject: [PATCH 04/16] Added a monitor object to guarantee the data synchronization --- src/tinystruct/examples/talk.java | 69 +++++++++++++++++-------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/tinystruct/examples/talk.java b/src/tinystruct/examples/talk.java index 2086085..36ded48 100644 --- a/src/tinystruct/examples/talk.java +++ b/src/tinystruct/examples/talk.java @@ -25,13 +25,13 @@ public class talk extends AbstractApplication { - private static final long TIMEOUT = 10; - private static final int DEFAULT_POOL_SIZE = 3; + private static final long TIMEOUT = 100; protected static final int DEFAULT_MESSAGE_POOL_SIZE = 10; protected final Map> meetings = new ConcurrentHashMap>(); protected final Map> list = new ConcurrentHashMap>(); protected final Map> sessions = new ConcurrentHashMap>(); private ExecutorService service; + private final Object monitor = new Object(); @Override public void init() { @@ -42,21 +42,21 @@ public void init() { if (this.service != null) { Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - @Override - public void run() { - service.shutdown(); - while (true) { - try { - System.out.println("Waiting for the service to terminate..."); - if (service.awaitTermination(5, TimeUnit.SECONDS)) { - System.out.println("Service will be terminated soon."); - break; - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } + @Override + public void run() { + service.shutdown(); + while (true) { + try { + System.out.println("Waiting for the service to terminate..."); + if (service.awaitTermination(5, TimeUnit.SECONDS)) { + System.out.println("Service will be terminated soon."); + break; + } + } catch (InterruptedException e) { + e.printStackTrace(); + } } + } })); } } @@ -115,7 +115,7 @@ public void run() { } private ExecutorService getService() { - return this.service!=null? this.service : Executors.newFixedThreadPool(DEFAULT_POOL_SIZE); + return this.service!=null? this.service : Executors.newSingleThreadExecutor(); } /** @@ -128,15 +128,16 @@ private ExecutorService getService() { public final String update(final String sessionId) throws ApplicationException, IOException { Builder message; Queue messages = this.list.get(sessionId); - while((message = messages.poll()) == null) { - try { - Thread.sleep(TIMEOUT); - } catch (InterruptedException e) { - throw new ApplicationException(e.getMessage(), e); + synchronized(monitor) { + while((message = messages.poll()) == null) { + try { + monitor.wait(TIMEOUT); + } catch (InterruptedException e) { + throw new ApplicationException(e.getMessage(), e); + } } + return message.toString(); } - - return message.toString(); } /** @@ -154,17 +155,21 @@ protected String filter(String text) { * @param builder */ private final void copy(Object meetingCode, Builder builder) { - final Collection>> set = this.list.entrySet(); - final Iterator>> iterator = set.iterator(); - final List _sessions; - if((_sessions = this.sessions.get(meetingCode)) != null) { - while(iterator.hasNext()) { - Entry> list = iterator.next(); - if(_sessions.contains(list.getKey())) { - list.getValue().add(builder); + final Collection>> set = this.list.entrySet(); + final Iterator>> iterator = set.iterator(); + final List _sessions; + + if((_sessions = this.sessions.get(meetingCode)) != null) { + while(iterator.hasNext()) { + Entry> list = iterator.next(); + if(_sessions.contains(list.getKey())) { + synchronized(monitor) { + list.getValue().add(builder); + monitor.notifyAll(); } } } + } } @Override From 3ddda0008059c8ae3425cdef96794dd7abb16c15 Mon Sep 17 00:00:00 2001 From: "James M. Zhou" Date: Tue, 4 Jul 2017 02:36:17 -0400 Subject: [PATCH 05/16] Update unstaged changes --- WEB-INF/classes/ApplicationGenerator.class | Bin 1663 -> 1663 bytes WEB-INF/classes/themes/reading.view | 138 +-- WEB-INF/classes/themes/smalltalk.view | 1033 +++++++++++------ .../examples/firstApplication.class | Bin 5158 -> 5158 bytes .../classes/tinystruct/examples/hello.class | Bin 3091 -> 3996 bytes .../classes/tinystruct/examples/image2.class | Bin 3609 -> 3606 bytes .../tinystruct/examples/reading$1.class | Bin 910 -> 910 bytes .../classes/tinystruct/examples/reading.class | Bin 19529 -> 19909 bytes .../tinystruct/examples/smalltalk.class | Bin 7871 -> 12318 bytes src/ApplicationGenerator.java | 1 - src/themes/smalltalk.view | 23 +- src/tinystruct/examples/hello.java | 20 + 12 files changed, 779 insertions(+), 436 deletions(-) diff --git a/WEB-INF/classes/ApplicationGenerator.class b/WEB-INF/classes/ApplicationGenerator.class index a1a6a236ce745b17998eb189e4976f3bd3bae8ff..e824e7372ab81e61672522aa04f7f94a5da11a31 100644 GIT binary patch delta 37 scmey*^PgwKA6DTC262WO1__1+25E*41{sDv2HDB{Y@&>5lU3QG0M0@QBme*a delta 37 scmey*^PgwKA6DUN262WO21$kn1{sD923dwa2D!=nY@&>rlU3QG0M6_QE&u=k diff --git a/WEB-INF/classes/themes/reading.view b/WEB-INF/classes/themes/reading.view index bf6539e..c5c86f0 100644 --- a/WEB-INF/classes/themes/reading.view +++ b/WEB-INF/classes/themes/reading.view @@ -7,23 +7,14 @@ + + {%book.name%} - + - - - - - - - - - - - + + + + + + + - -

{%book.name%}

- +
[%book.info%]
+
{%content%}
+ +
- - - - -

© 2015

- - - - - + + + + + diff --git a/WEB-INF/classes/themes/smalltalk.view b/WEB-INF/classes/themes/smalltalk.view index 31e686b..5c89baa 100644 --- a/WEB-INF/classes/themes/smalltalk.view +++ b/WEB-INF/classes/themes/smalltalk.view @@ -6,360 +6,717 @@ - - + Small Talk - - - + + - - + - - - - - + + + + + if(!$("#topic").text()) { + $("#topic_modal").modal(); + } + + $("#link").click(function(){ + $.ajax({ + type: "POST", + url: "[%LINK:talk/matrix%]/", + data: {meeting_code: "{%meeting_code%}"} + }).done(function( msg ) { + $("#matrix").css({"background":"url("+msg+") transparent center center"}); + $("#matrix").show(); + }); + }); + + $("#link").mouseover(function(){ + $("#matrix").show(); + }); + + $("#link").mouseout(function(){ + $("#matrix").hide(); + }); + + $("#text").on('paste', function (e) { + if(e.originalEvent) { + var original = e.originalEvent; + for (var i = 0; i < original.clipboardData.items.length; i++) { + if (original.clipboardData.items[i].kind == "file" && original.clipboardData.items[i].type == "image/png") { + var file = original.clipboardData.items[i].getAsFile(); + var reader = new FileReader(); + reader.onloadend = function () { + var img = $(""); + img.attr('src', this.result); + $('#text').html(img); + } + reader.readAsDataURL(file); + break; + } + } + } + }); + + $("#attachment").fileinput({ + uploadAsync: false, + showPreview: false, + showCaption: false, + maxFileCount: 2, + uploadUrl: "/?q=talk/upload", // server upload action + }); + + $("#attachment").on('filebatchuploadsuccess', function(event, data, previewId, index) { + var form = data.form, files = data.files, extra = data.extra, + response = data.response, reader = data.reader; + + $ul = $("