You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2017/08/31 02:30:41 UTC
[1/2] openmeetings git commit: [OPENMEETINGS-1638] initial attempt to
implement recording in the room
Repository: openmeetings
Updated Branches:
refs/heads/master 3ede291a3 -> 5fd782fcb
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/interviewwb.js
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/interviewwb.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/interviewwb.js
index 2aa8426..56e2c9e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/interviewwb.js
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/interviewwb.js
@@ -18,9 +18,10 @@
*/
var NONE = 'none';
var WbArea = (function() {
- var container, area, role = NONE, self = {}, choose, btns, _inited = false;
+ var container, area, role = NONE, self = {}, choose, btns
+ , _inited = false, recStart;
- self.init = function() {
+ function _init() {
container = $(".room.wb.area");
area = container.find(".wb-area");
btns = $('.pod-row .pod-container .pod a.choose-btn');
@@ -36,9 +37,13 @@ var WbArea = (function() {
choose.find('.pod-name').val($(this).data('pod'));
return false;
});
- $('.pod-row .pod-container a.rec-btn.start').button({
+ recStart = $('.pod-row .pod-container a.rec-btn.start');
+ recStart.button({
disabled: true
, icon: "ui-icon-play"
+ }).click(function() {
+ wbAction('startRecording', '');
+ return false;
});
$('.pod-row .pod-container a.rec-btn.stop').button({
disabled: true
@@ -65,8 +70,8 @@ var WbArea = (function() {
]
});
_inited = true;
- };
- self.setRole = function(_role) {
+ }
+ function _setRole(_role) {
if (!_inited) return;
role = _role;
if (role !== NONE) {
@@ -75,13 +80,20 @@ var WbArea = (function() {
btns.hide();
}
}
- self.destroy = function() {
- };
- self.resize = function(posX, w, h) {
+ function _resize(posX, w, h) {
if (!container || !_inited) return;
var hh = h - 5;
container.width(w).height(h).css('left', posX + "px");
area.width(w).height(hh);
}
+ function _setRecStartEnabled(en) {
+ recStart.button("option", "disabled", !en);
+ }
+
+ self.init = _init;
+ self.destroy = function() {};
+ self.setRole = _setRole;
+ self.resize = _resize;
+ self.setRecStartEnabled = _setRecStartEnabled;
return self;
})();
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
index fc454eb..4d4d750 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
@@ -40,16 +40,16 @@
<context:annotation-config />
<context:component-scan base-package="org.apache.openmeetings" />
+ <!-- Start of Services exposed to red5 -->
<bean id="web.handler" class="org.apache.openmeetings.core.remote.ScopeApplicationAdapter" />
+ <bean id="mobile.service" class="org.apache.openmeetings.core.remote.MobileService" />
+ <!-- End of Services exposed to red5 -->
+ <bean id="mainservice" class="org.apache.openmeetings.core.remote.MainService" />
+ <bean id="recordingservice" class="org.apache.openmeetings.core.remote.RecordingService" />
<bean id="openmeetings.SessionManager" class="org.apache.openmeetings.core.session.SessionManager"/>
-
- <!-- Start of Services -->
- <bean id="xmlcrm.service" class="org.apache.openmeetings.core.remote.MainService" />
<bean id="openmeetings.FileProcessor" class="org.apache.openmeetings.core.data.file.FileProcessor" />
<bean id="openmeetings.FlvExplorerConverter" class="org.apache.openmeetings.core.converter.FlvExplorerConverter" />
- <bean id="recordingservice.service" class="org.apache.openmeetings.core.remote.RecordingService" />
- <bean id="mobile.service" class="org.apache.openmeetings.core.remote.MobileService" />
<bean id="openmeetings.RecordingConverterTask" class="org.apache.openmeetings.core.data.record.converter.RecordingConverterTask" />
<bean id="openmeetings.InterviewConverterTask" class="org.apache.openmeetings.core.data.record.converter.InterviewConverterTask" />
<bean id="openmeetings.InterviewConverter" class="org.apache.openmeetings.core.converter.InterviewConverter" />
@@ -151,7 +151,7 @@
<bean id="configurationDaoImpl" class="org.apache.openmeetings.db.dao.basic.ConfigurationDao" />
<bean id="appointmentDao" class="org.apache.openmeetings.db.dao.calendar.AppointmentDao" />
<bean id="appointmentLogic" class="org.apache.openmeetings.service.calendar.AppointmentLogic" />
- <bean id="sessionManagement" class="org.apache.openmeetings.db.dao.server.SessiondataDao" />
+ <bean id="sessionDao" class="org.apache.openmeetings.db.dao.server.SessiondataDao" />
<bean id="userManagement" class="org.apache.openmeetings.service.user.UserManager" />
<bean id="roomModeratorDao" class="org.apache.openmeetings.db.dao.room.RoomModeratorDao" />
<bean id="roomGroupDao" class="org.apache.openmeetings.db.dao.room.RoomGroupDao"/>
[2/2] openmeetings git commit: [OPENMEETINGS-1638] initial attempt to
implement recording in the room
Posted by so...@apache.org.
[OPENMEETINGS-1638] initial attempt to implement recording in the room
Project: http://git-wip-us.apache.org/repos/asf/openmeetings/repo
Commit: http://git-wip-us.apache.org/repos/asf/openmeetings/commit/5fd782fc
Tree: http://git-wip-us.apache.org/repos/asf/openmeetings/tree/5fd782fc
Diff: http://git-wip-us.apache.org/repos/asf/openmeetings/diff/5fd782fc
Branch: refs/heads/master
Commit: 5fd782fcbf365dbaf54b09a26dd978ba403662c2
Parents: 3ede291
Author: Maxim Solodovnik <so...@gmail.com>
Authored: Thu Aug 31 00:13:12 2017 +0700
Committer: Maxim Solodovnik <so...@gmail.com>
Committed: Thu Aug 31 00:13:12 2017 +0700
----------------------------------------------------------------------
.../openmeetings/core/remote/MobileService.java | 6 +-
.../core/remote/RecordingService.java | 185 ++++----
.../core/remote/ScopeApplicationAdapter.java | 204 ++-------
.../core/session/SessionManager.java | 34 +-
.../test/rtmp/LoadTestRtmpClient.java | 2 +-
.../org/apache/openmeetings/IApplication.java | 16 +-
.../db/dao/server/ISessionManager.java | 13 +-
.../openmeetings/db/entity/basic/Client.java | 120 +++--
.../openmeetings/db/entity/basic/IClient.java | 10 +
.../db/entity/room/StreamClient.java | 44 +-
.../web/admin/connection/ConnectionsPanel.java | 2 +-
.../openmeetings/web/admin/rooms/RoomForm.java | 2 +-
.../openmeetings/web/app/Application.java | 18 +-
.../apache/openmeetings/web/room/RoomPanel.java | 38 +-
.../web/room/wb/AbstractWbPanel.java | 72 ++-
.../web/room/wb/InterviewWbPanel.java | 28 +-
.../openmeetings/web/room/wb/WbAction.java | 2 +
.../openmeetings/web/room/wb/WbPanel.java | 437 +++++++++----------
.../openmeetings/web/room/wb/interviewwb.js | 28 +-
.../WEB-INF/classes/applicationContext.xml | 12 +-
20 files changed, 657 insertions(+), 616 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
index 6ea3bee..af7b106 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
@@ -216,7 +216,7 @@ public class MobileService {
public StreamClient create(User u, Sessiondata sd) {
StreamClient c = new StreamClient();
c.setType(StreamClient.Type.mobile);
- c.setOwnerSid(sd.getSessionId());
+ c.setSid(sd.getSessionId());
c.setUid(UUID.randomUUID().toString());
return create(c, u);
}
@@ -226,7 +226,7 @@ public class MobileService {
c.setFirstname(u.getFirstname());
c.setLastname(u.getLastname());
if (c.getUserId() != null) {
- c.setUsername(u.getLogin());
+ c.setLogin(u.getLogin());
c.setFirstname(u.getFirstname());
c.setLastname(u.getLastname());
c.setEmail(u.getAddress() == null ? null : u.getAddress().getEmail());
@@ -274,7 +274,7 @@ public class MobileService {
add(map, "firstname", c.getFirstname());
add(map, "lastname", c.getLastname());
add(map, "publicSid", c.getUid());
- add(map, "login", c.getUsername());
+ add(map, "login", c.getLogin());
add(map, "email", c.getEmail());
add(map, "avsettings", c.getAvsettings());
add(map, "interviewPodId", c.getInterviewPodId());
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
index 0b086d5..81ce1fc 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
@@ -18,6 +18,7 @@
*/
package org.apache.openmeetings.core.remote;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.getApp;
import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
import java.util.Date;
@@ -25,6 +26,7 @@ import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import org.apache.openmeetings.IApplication;
import org.apache.openmeetings.core.converter.BaseConverter;
import org.apache.openmeetings.core.data.record.converter.InterviewConverterTask;
import org.apache.openmeetings.core.data.record.converter.RecordingConverterTask;
@@ -37,6 +39,7 @@ import org.apache.openmeetings.db.dao.record.RecordingMetaDeltaDao;
import org.apache.openmeetings.db.dao.server.ISessionManager;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.basic.IClient;
import org.apache.openmeetings.db.entity.file.FileItem.Type;
import org.apache.openmeetings.db.entity.record.Recording;
import org.apache.openmeetings.db.entity.record.RecordingMetaData;
@@ -95,7 +98,7 @@ public class RecordingService implements IPendingServiceCallback {
return "rec_" + recordingId + "_stream_" + streamid + "_" + dateString;
}
- public String recordMeetingStream(IConnection current, StreamClient client, String roomRecordingName, String comment, boolean isInterview) {
+ public void startRecording(IScope scope, IClient client, boolean isInterview) {
try {
log.debug("##REC:: recordMeetingStream ::");
@@ -106,24 +109,23 @@ public class RecordingService implements IPendingServiceCallback {
Recording recording = new Recording();
recording.setHash(UUID.randomUUID().toString());
- recording.setName(roomRecordingName);
+ recording.setName(String.format("%s %s", isInterview ? "Interview" : "Recording", CalendarPatterns.getDateWithTimeByMiliSeconds(new Date())));
Long ownerId = client.getUserId();
- if (ownerId != null && ownerId < 0) {
- User c = userDao.get(-ownerId);
- if (c != null) {
- ownerId = c.getOwnerId();
- }
+ User u = userDao.get(ownerId);
+ if (u != null && User.Type.contact == u.getType()) {
+ ownerId = u.getOwnerId();
}
recording.setInsertedBy(ownerId);
recording.setType(Type.Recording);
- recording.setComment(comment);
recording.setInterview(isInterview);
recording.setRoomId(roomId);
recording.setRecordStart(now);
- recording.setWidth(client.getWidth());
- recording.setHeight(client.getHeight());
+ if (!isInterview) {
+ recording.setWidth(client.getWidth());
+ recording.setHeight(client.getHeight());
+ }
recording.setOwnerId(ownerId);
recording.setStatus(Recording.Status.RECORDING);
@@ -135,10 +137,17 @@ public class RecordingService implements IPendingServiceCallback {
// Update Client and set Flag
client.setRecordingStarted(true);
client.setRecordingId(recordingId);
+ if (!(client instanceof Client)) {
+ IApplication iapp = getApp();
+ Client c = iapp.getOmClientBySid(client.getSid());
+ c.setRecordingId(recordingId);
+ c.setRecordingStarted(true);
+ iapp.update(c);
+ }
sessionManager.update(client);
// get all stream and start recording them
- for (IConnection conn : current.getScope().getClientConnections()) {
+ for (IConnection conn : scope.getClientConnections()) {
if (conn != null) {
if (conn instanceof IServiceCapableConnection) {
StreamClient rcl = sessionManager.get(IClientUtil.getId(conn.getClient()));
@@ -192,13 +201,77 @@ public class RecordingService implements IPendingServiceCallback {
}
}
// Send every user a notification that the recording did start
- WebSocketHelper.sendRoom(new TextRoomMessage(roomId, ownerId, RoomMessage.Type.recordingStarted, client.getOwnerSid()));
- return roomRecordingName;
+ WebSocketHelper.sendRoom(new TextRoomMessage(roomId, ownerId, RoomMessage.Type.recordingStarted, client.getSid()));
+ } catch (Exception err) {
+ log.error("[startRecording]", err);
+ }
+ }
+
+ public void stopRecording(IScope scope, IClient client) {
+ try {
+ log.debug("stopRecordAndSave {}, {}", client.getLogin(), client.getRemoteAddress());
+ IApplication iapp = getApp();
+ Client recClient = null;
+ for (Client c : iapp.getOmRoomClients(client.getRoomId())) {
+ if (c.getRecordingId() != null) {
+ recClient = c;
+ break;
+ }
+ }
+ if (recClient == null) {
+ log.error("Unable to find recordingId on recording stop");
+ return;
+ }
+ WebSocketHelper.sendRoom(new TextRoomMessage(recClient.getRoomId(), recClient.getUserId(), RoomMessage.Type.recordingStoped, recClient.getSid()));
+
+ // get all stream and stop recording them
+ for (IConnection conn : scope.getClientConnections()) {
+ if (conn != null) {
+ if (conn instanceof IServiceCapableConnection) {
+ StreamClient rcl = sessionManager.get(IClientUtil.getId(conn.getClient()));
+
+ if (rcl == null) {
+ continue;
+ }
+ log.debug("is this users still alive? stop it : {}", rcl);
+ if (Client.Type.sharing == rcl.getType()) {
+ if (rcl.getRecordingId() != null && (rcl.isSharingStarted() || rcl.isRecordingStarted())) {
+ // Stop FLV Recording
+ stopRecordingShow(scope, rcl.getBroadCastId(), rcl.getMetaId());
+
+ // Update Meta Data
+ metaDataDao.updateEndDate(rcl.getMetaId(), new Date());
+ }
+ } else if (rcl.getAvsettings().equals("av") || rcl.getAvsettings().equals("a") || rcl.getAvsettings().equals("v")) {
+ stopRecordingShow(scope, rcl.getBroadCastId(), rcl.getMetaId());
+
+ // Update Meta Data
+ metaDataDao.updateEndDate(rcl.getMetaId(), new Date());
+ }
+ }
+ }
+ }
+ // Store to database
+ Long recordingId = recClient.getRecordingId();
+
+ recordingDao.updateEndTime(recordingId, new Date());
+
+ // Reset values
+ recClient.setRecordingId(null);
+ recClient.setRecordingStarted(false);
+ sessionManager.update(recClient);
+ log.debug("recordingConverterTask {}", recordingConverterTask);
+
+ Recording recording = recordingDao.get(recordingId);
+ if (recording.isInterview()) {
+ interviewConverterTask.startConversionThread(recordingId);
+ } else {
+ recordingConverterTask.startConversionThread(recordingId);
+ }
} catch (Exception err) {
- log.error("[recordMeetingStream]", err);
+ log.error("[-- stopRecording --]", err);
}
- return null;
}
/**
@@ -250,8 +323,8 @@ public class RecordingService implements IPendingServiceCallback {
*/
public void stopRecordingShow(IScope scope, String broadcastId, Long metaId) {
try {
- log.debug("** stopRecordingShow: " + scope);
- log.debug("### Stop recording show for broadcastId: " + broadcastId + " || " + scope.getContextPath());
+ log.debug("** stopRecordingShow: {}", scope);
+ log.debug("### Stop recording show for broadcastId: {} || {}", broadcastId, scope.getContextPath());
IBroadcastStream stream = scopeApplicationAdapter.getBroadcastStream(scope, broadcastId);
@@ -282,10 +355,10 @@ public class RecordingService implements IPendingServiceCallback {
// this would normally happen in the Listener
Status s = metaData.getStreamStatus();
if (Status.NONE == s) {
- log.debug("Stream was not started, no need to stop :: stream with id " + metaId);
+ log.debug("Stream was not started, no need to stop :: stream with id {}", metaId);
} else {
metaData.setStreamStatus(listenerAdapter == null && s == Status.STARTED ? Status.STOPPED : Status.STOPPING);
- log.debug("Stopping the stream :: New status == " + metaData.getStreamStatus());
+ log.debug("Stopping the stream :: New status == {}", metaData.getStreamStatus());
}
metaDataDao.update(metaData);
if (listenerAdapter == null) {
@@ -293,7 +366,7 @@ public class RecordingService implements IPendingServiceCallback {
log.debug("Available Streams :: " + streamListeners.size());
for (Long entryKey : streamListeners.keySet()) {
- log.debug("Stored recordingMetaDataId in Map: " + entryKey);
+ log.debug("Stored recordingMetaDataId in Map: {}", entryKey);
}
throw new IllegalStateException("Could not find Listener to stop! recordingMetaDataId " + metaId);
}
@@ -306,78 +379,12 @@ public class RecordingService implements IPendingServiceCallback {
}
}
- public void stopRecordAndSave(IScope scope, StreamClient client, Long storedRecordingId) {
- try {
- log.debug("stopRecordAndSave " + client.getUsername() + "," + client.getUserip());
- WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.recordingStoped, client.getOwnerSid()));
-
- // get all stream and stop recording them
- for (IConnection conn : scope.getClientConnections()) {
- if (conn != null) {
- if (conn instanceof IServiceCapableConnection) {
- StreamClient rcl = sessionManager.get(IClientUtil.getId(conn.getClient()));
-
- if (rcl == null) {
- continue;
- }
- log.debug("is this users still alive? stop it :" + rcl);
-
- if (Client.Type.sharing == rcl.getType()) {
- if (rcl.getRecordingId() != null && (rcl.isSharingStarted() || rcl.isRecordingStarted())) {
- // Stop FLV Recording
- stopRecordingShow(scope, rcl.getBroadCastId(), rcl.getMetaId());
-
- // Update Meta Data
- metaDataDao.updateEndDate(rcl.getMetaId(), new Date());
- }
- } else if (rcl.getAvsettings().equals("av") || rcl.getAvsettings().equals("a") || rcl.getAvsettings().equals("v")) {
- stopRecordingShow(scope, rcl.getBroadCastId(), rcl.getMetaId());
-
- // Update Meta Data
- metaDataDao.updateEndDate(rcl.getMetaId(), new Date());
- }
- }
- }
- }
- // Store to database
- Long recordingId = client.getRecordingId();
-
- // In the Case of an Interview the stopping client does not mean
- // that its actually the recording client
- if (storedRecordingId != null) {
- recordingId = storedRecordingId;
- }
-
- if (recordingId != null) {
- recordingDao.updateEndTime(recordingId, new Date());
-
- // Reset values
- client.setRecordingId(null);
- client.setRecordingStarted(false);
-
- sessionManager.update(client);
- log.debug("recordingConverterTask {}", recordingConverterTask);
-
- Recording recording = recordingDao.get(recordingId);
- if (!recording.isInterview()) {
- recordingConverterTask.startConversionThread(recordingId);
- } else {
- interviewConverterTask.startConversionThread(recordingId);
- }
- }
- } catch (Exception err) {
- log.error("[-- stopRecordAndSave --]", err);
- }
- }
-
public void stopRecordingShowForClient(IScope scope, StreamClient rcl) {
try {
- // this cannot be handled here, as to stop a stream and to leave a
- // room is not
+ // this cannot be handled here, as to stop a stream and to leave a room is not
// the same type of event.
- // StreamService.addRoomClientEnterEventFunc(rcl, roomrecordingName,
- // rcl.getUserip(), false);
- log.debug("### stopRecordingShowForClient: " + rcl);
+ // StreamService.addRoomClientEnterEventFunc(rcl, roomrecordingName, rcl.getUserip(), false);
+ log.debug("### stopRecordingShowForClient: {}", rcl);
if (Client.Type.sharing == rcl.getType()) {
if (rcl.getRecordingId() != null && rcl.isSharingStarted()) {
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
index 5804cf9..f3b9636 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ScopeApplicationAdapter.java
@@ -39,7 +39,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -62,7 +61,6 @@ import org.apache.openmeetings.db.entity.basic.Client;
import org.apache.openmeetings.db.entity.log.ConferenceLog;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.room.StreamClient;
-import org.apache.openmeetings.util.CalendarPatterns;
import org.apache.openmeetings.util.InitializationContainer;
import org.apache.openmeetings.util.NullStringer;
import org.apache.openmeetings.util.OmFileHelper;
@@ -125,6 +123,10 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
@Autowired
private RecordingDao recordingDao;
+ public static IApplication getApp() {
+ return (IApplication)Application.get(wicketApplicationName);
+ }
+
@Override
public void resultReceived(IPendingServiceCall arg0) {
if (_log.isTraceEnabled()) {
@@ -167,7 +169,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
InitializationContainer.initComplete = true;
// Init properties
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
+ IApplication iapp = getApp();
iapp.setXFrameOptions(cfgDao.getConfValue(CONFIG_HEADER_XFRAME, String.class, HEADER_XFRAME_SAMEORIGIN));
iapp.setContentSecurityPolicy(cfgDao.getConfValue(CONFIG_HEADER_CSP, String.class, HEADER_CSP_SELF));
iapp.updateJpaAddresses(cfgDao);
@@ -232,15 +234,15 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
rcm.setType(Client.Type.room);
}
rcm.setUid(Strings.isEmpty(uid) ? UUID.randomUUID().toString() : uid);
- rcm.setOwnerSid(ownerSid);
- if (sipDao.getUid() != null && sipDao.getUid().equals(rcm.getOwnerSid())) {
+ rcm.setSid(ownerSid);
+ if (sipDao.getUid() != null && sipDao.getUid().equals(rcm.getSid())) {
rcm.setType(Client.Type.sip);
}
rcm.setUserport(conn.getRemotePort());
- rcm.setUserip(conn.getRemoteAddress());
+ rcm.setRemoteAddress(conn.getRemoteAddress());
rcm.setSwfurl(swfURL);
rcm.setTcUrl(tcUrl);
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
+ IApplication iapp = getApp();
Number width = (Number)connParams.get(WIDTH_PARAM);
Number height = (Number)connParams.get(HEIGHT_PARAM);
if (width != null && height != null) {
@@ -260,7 +262,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
// Log the User
conferenceLogDao.add(ConferenceLog.Type.clientConnect,
- rcm.getUserId(), streamId, null, rcm.getUserip(),
+ rcm.getUserId(), streamId, null, rcm.getRemoteAddress(),
rcm.getScope());
return true;
}
@@ -289,7 +291,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
returnMap.put("result", "stopRecordingOnly");
- recordingService.stopRecordAndSave(current.getScope(), client, null);
+ recordingService.stopRecording(current.getScope(), client);
}
if (Boolean.parseBoolean("" + map.get("stopPublishing")) && client.isPublishStarted()) {
changed = true;
@@ -442,7 +444,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
sendStreamClosed(client);
}
- _log.debug("removing Username {} {}, streamid: {}", client.getUsername()
+ _log.debug("removing Username {} {}, streamid: {}", client.getLogin()
, client.getConnectedSince(), client.getId());
// stop and save any recordings
@@ -450,9 +452,9 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
_log.debug("*** roomLeave Current Client is Recording - stop that");
if (client.getInterviewPodId() != null) {
//interview, TODO need better check
- _stopInterviewRecording(client, scope);
+ stopInterviewRecording(client);
} else {
- recordingService.stopRecordAndSave(scope, client, null);
+ recordingService.stopRecording(scope, client);
}
}
recordingService.stopRecordingShowForClient(scope, client);
@@ -462,8 +464,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
_log.debug("currentScope " + scope);
if (Client.Type.mobile == client.getType() || Client.Type.sip == client.getType()) {
- IApplication app = (IApplication)Application.get(wicketApplicationName);
- app.exit(client.getUid());
+ getApp().exit(client.getUid());
}
sessionManager.remove(client.getUid());
} catch (Exception err) {
@@ -500,8 +501,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
}
}
if (Client.Type.sip == c.getType()) {
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
- Client cl = iapp.getOmClientBySid(c.getOwnerSid());
+ Client cl = getApp().getOmClientBySid(c.getSid());
String newNumber = getSipTransportLastname(c.getRoomId());
cl.getUser().setLastname(newNumber);
c.setLastname(newNumber);
@@ -509,8 +509,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
}
sessionManager.update(c);
if (Client.Type.sharing == c.getType() && c.isRecordingStarted()) {
- String recordingName = "Recording " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
- recordingService.recordMeetingStream(current, c, recordingName, "", false);
+ recordingService.startRecording(current.getScope(), c, false);
}
_log.debug("newStream SEND: {}", c);
@@ -551,7 +550,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
}
}.start();
JSONObject obj = new JSONObject()
- .put("ownerSid", c.getOwnerSid())
+ .put("ownerSid", c.getSid())
.put("uid", c.getUid())
.put("type", c.getType())
.put("streamId", current.getClient().getId())
@@ -615,7 +614,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
private static void sendSharingStoped(StreamClient rcl) {
JSONObject obj = new JSONObject()
- .put("ownerSid", rcl.getOwnerSid())
+ .put("ownerSid", rcl.getSid())
.put("uid", rcl.getUid());
WebSocketHelper.sendRoom(new TextRoomMessage(rcl.getRoomId(), rcl.getUserId(), RoomMessage.Type.sharingStoped, obj.toString()));
}
@@ -623,7 +622,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
private static void sendStreamClosed(StreamClient rcl) {
JSONObject obj = new JSONObject()
.put("uid", rcl.getUid())
- .put("ownerSid", rcl.getOwnerSid())
+ .put("ownerSid", rcl.getSid())
.put("broadcastId", rcl.getBroadCastId());
WebSocketHelper.sendRoom(new TextRoomMessage(rcl.getRoomId(), rcl.getUserId(), RoomMessage.Type.closeStream, obj.toString()));
}
@@ -718,20 +717,6 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
}
/**
- * Only temporary for load test, with return argument for the client to have a result
- *
- * @param remoteMethodName
- * @param newMessage
- * @param sendSelf
- * @return true
- */
- @Deprecated
- public boolean loadTestSyncMessage(String remoteMethodName, Object newMessage, boolean sendSelf) {
- sendMessageToCurrentScope(remoteMethodName, newMessage, sendSelf, false);
- return true;
- }
-
- /**
* General sync mechanism for all messages that are send from within the
* scope of the current client, but:
* <ul>
@@ -927,83 +912,6 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
return 1;
}
- /**
- * @deprecated this method should be reworked to use a single SQL query in
- * the cache to get any client in the current room that is
- * recording instead of iterating through connections!
- * @return true in case there is recording session, false otherwise, null if any exception happend
- */
- @Deprecated
- public boolean getInterviewRecordingStatus() {
- try {
- IConnection current = Red5.getConnectionLocal();
-
- for (IConnection conn : current.getScope().getClientConnections()) {
- if (conn != null) {
- StreamClient rcl = sessionManager.get(IClientUtil.getId(conn.getClient()));
-
- if (rcl != null && rcl.isRecordingStarted()) {
- return true;
- }
- }
- }
- } catch (Exception err) {
- _log.error("[getInterviewRecordingStatus]", err);
- }
- return false;
- }
-
- /**
- * @deprecated @see {@link ScopeApplicationAdapter#getInterviewRecordingStatus()}
- * @return - false if there were existing recording, true if recording was started successfully, null if any exception happens
- */
- @Deprecated
- public boolean startInterviewRecording() {
- try {
- _log.debug("----------- startInterviewRecording");
- IConnection current = Red5.getConnectionLocal();
-
- for (IConnection conn : current.getScope().getClientConnections()) {
- if (conn != null) {
- StreamClient rcl = sessionManager.get(IClientUtil.getId(conn.getClient()));
-
- if (rcl != null && rcl.isRecordingStarted()) {
- return false;
- }
- }
- }
- StreamClient rcl = sessionManager.get(IClientUtil.getId(current.getClient()));
-
- // Also set the Recording Flag to Record all Participants that enter later
- rcl.setRecordingStarted(true);
- sessionManager.update(rcl);
-
- Map<String, String> interviewStatus = new HashMap<>();
- interviewStatus.put("action", "start");
-
- for (IConnection conn : current.getScope().getClientConnections()) {
- if (conn != null) {
- IClient client = conn.getClient();
- if (IClientUtil.isSharing(client)) {
- // screen sharing clients do not receive events
- continue;
- }
-
- ((IServiceCapableConnection) conn).invoke("interviewStatus", new Object[] { interviewStatus }, this);
- _log.debug("-- startInterviewRecording " + interviewStatus);
- }
- }
- String recordingName = "Interview " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
-
- recordingService.recordMeetingStream(current, rcl, recordingName, "", true);
-
- return true;
- } catch (Exception err) {
- _log.debug("[startInterviewRecording]", err);
- }
- return false;
- }
-
@SuppressWarnings({ "rawtypes" })
public boolean sendRemoteCursorEvent(final String streamid, Map messageObj) {
new MessageSender("sendRemoteCursorEvent", messageObj, this) {
@@ -1018,14 +926,18 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
}
/**
- * Stop the recording of the streams and send event to connected users of scope
+ * Starts recording in interview room
*
- * @return true if interview was found
+ * @return - false if there were existing recording, true if recording was started successfully, null if any exception happens
*/
- public boolean stopInterviewRecording() {
- IConnection current = Red5.getConnectionLocal();
- StreamClient currentClient = sessionManager.get(IClientUtil.getId(current.getClient()));
- return _stopInterviewRecording(currentClient, current.getScope());
+ public void startInterviewRecording(Client c) {
+ _log.debug("----------- startInterviewRecording");
+
+ if (c == null || sessionManager.getRecordingCount(c.getRoom().getId()) > 0) {
+ return;
+ }
+
+ recordingService.startRecording(getRoomScope("" + c.getRoom().getId()), c, true);
}
/**
@@ -1033,46 +945,9 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
*
* @return true if interview was found
*/
- private boolean _stopInterviewRecording(StreamClient currentClient, IScope currentScope) {
- try {
- _log.debug("----------- stopInterviewRecording");
- Long clientRecordingId = currentClient.getRecordingId();
-
- for (IConnection conn : currentScope.getClientConnections()) {
- Long recordingId = null;
- if (conn != null) {
- StreamClient rcl = sessionManager.get(IClientUtil.getId(conn.getClient()));
- if (rcl != null && rcl.isRecordingStarted()) {
- rcl.setRecordingStarted(false);
- recordingId = rcl.getRecordingId();
- rcl.setRecordingId(null);
-
- // Reset the Recording Flag to Record all
- // Participants that enter later
- sessionManager.update(rcl);
- }
- }
- if (recordingId != null) {
- clientRecordingId = recordingId;
- }
- }
- if (clientRecordingId == null) {
- _log.debug("stopInterviewRecording:: unable to find recording client");
- return false;
- }
-
- recordingService.stopRecordAndSave(scope, currentClient, clientRecordingId);
-
- Map<String, String> interviewStatus = new HashMap<>();
- interviewStatus.put("action", "stop");
-
- sendMessageToCurrentScope("interviewStatus", interviewStatus, true);
- return true;
-
- } catch (Exception err) {
- _log.debug("[stopInterviewRecording]", err);
- }
- return false;
+ public void stopInterviewRecording(org.apache.openmeetings.db.entity.basic.IClient c) {
+ _log.debug("----------- stopInterviewRecording");
+ recordingService.stopRecording(getRoomScope("" + c.getRoomId()), c);
}
public IScope getRoomScope(String room) {
@@ -1090,7 +965,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
IConnection current = Red5.getConnectionLocal();
StreamClient client = sessionManager.get(IClientUtil.getId(current.getClient()));
WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.audioActivity
- , new JSONObject().put("sid", client.getOwnerSid()).put("active", active).toString()));
+ , new JSONObject().put("sid", client.getSid()).put("active", active).toString()));
}
/*
@@ -1100,8 +975,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
List<String> ids = new ArrayList<>();
IConnection current = Red5.getConnectionLocal();
StreamClient client = sessionManager.get(IClientUtil.getId(current.getClient()));
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
- for (Client c: iapp.getOmRoomClients(client.getRoomId()) ) {
+ for (Client c: getApp().getOmRoomClients(client.getRoomId()) ) {
for (Client.Stream s : c.getStreams()) {
ids.add(s.getBroadcastId());
}
@@ -1137,7 +1011,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
}
public List<Long> getActiveRoomIds() {
- return new ArrayList<>(((IApplication)Application.get(wicketApplicationName)).getActiveRoomIds());
+ return new ArrayList<>(getApp().getActiveRoomIds());
}
public synchronized int updateSipTransport() {
@@ -1149,8 +1023,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
String newNumber = getSipTransportLastname(count);
_log.debug("getSipConferenceMembersNumber: " + newNumber);
if (!newNumber.equals(client.getLastname())) {
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
- Client cl = iapp.getOmClientBySid(client.getOwnerSid());
+ Client cl = getApp().getOmClientBySid(client.getSid());
cl.getUser().setLastname(newNumber);
client.setLastname(newNumber);
sessionManager.update(client);
@@ -1169,8 +1042,7 @@ public class ScopeApplicationAdapter extends MultiThreadedApplicationAdapter imp
public CheckDto check() {
IConnection current = Red5.getConnectionLocal();
StreamClient c = sessionManager.get(IClientUtil.getId(current.getClient()));
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
- Client cl = iapp.getOmClientBySid(c.getOwnerSid());
+ Client cl = getApp().getOmClientBySid(c.getSid());
return new CheckDto(cl);
}
}
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
index 869075a..12cf66f 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
@@ -18,8 +18,8 @@
*/
package org.apache.openmeetings.core.session;
+import static org.apache.openmeetings.core.remote.ScopeApplicationAdapter.getApp;
import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.wicketApplicationName;
import java.util.Collection;
import java.util.Date;
@@ -32,8 +32,8 @@ import java.util.stream.Collectors;
import org.apache.openmeetings.IApplication;
import org.apache.openmeetings.db.dao.server.ISessionManager;
import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.basic.IClient;
import org.apache.openmeetings.db.entity.room.StreamClient;
-import org.apache.wicket.Application;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.Server;
import org.slf4j.Logger;
@@ -50,8 +50,7 @@ public class SessionManager implements ISessionManager {
protected static final Logger log = Red5LoggerFactory.getLogger(SessionManager.class, webAppRootKey);
private static Map<String, StreamClient> getClients() {
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
- return iapp.getStreamClients();
+ return getApp().getStreamClients();
}
@Override
@@ -59,11 +58,12 @@ public class SessionManager implements ISessionManager {
if (c == null) {
return null;
}
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
+ IApplication iapp = getApp();
c.setServerId(iapp.getServerId());
c.setConnectedSince(new Date());
c.setRoomEnter(new Date());
- return iapp.update(c);
+ iapp.update(c);
+ return c;
}
@Override
@@ -80,9 +80,8 @@ public class SessionManager implements ISessionManager {
}
@Override
- public StreamClient update(StreamClient rcm) {
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
- return iapp.update(rcm);
+ public void update(IClient rcm) {
+ getApp().update(rcm);
}
@Override
@@ -102,20 +101,6 @@ public class SessionManager implements ISessionManager {
}
@Override
- public Collection<StreamClient> listByRoomAll(Long roomId) {
- return list().stream()
- .filter(c -> roomId.equals(c.getRoomId()))
- .collect(Collectors.toList());
- }
-
- @Override
- public List<StreamClient> listModeratorByRoom(Long roomId) {
- return list().stream()
- .filter(c -> roomId.equals(c.getRoomId()) && c.isMod())
- .collect(Collectors.toList());
- }
-
- @Override
public long getRecordingCount(Long roomId) {
if (roomId == null) {
return 0;
@@ -137,8 +122,7 @@ public class SessionManager implements ISessionManager {
@Override
public Set<Long> getActiveRoomIds() {
- IApplication iapp = (IApplication)Application.get(wicketApplicationName);
- return iapp.getActiveRoomIds();
+ return getApp().getActiveRoomIds();
}
@Override
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-core/src/test/java/org/apache/openmeetings/test/rtmp/LoadTestRtmpClient.java
----------------------------------------------------------------------
diff --git a/openmeetings-core/src/test/java/org/apache/openmeetings/test/rtmp/LoadTestRtmpClient.java b/openmeetings-core/src/test/java/org/apache/openmeetings/test/rtmp/LoadTestRtmpClient.java
index 3a2a886..8d29056 100644
--- a/openmeetings-core/src/test/java/org/apache/openmeetings/test/rtmp/LoadTestRtmpClient.java
+++ b/openmeetings-core/src/test/java/org/apache/openmeetings/test/rtmp/LoadTestRtmpClient.java
@@ -86,7 +86,7 @@ public class LoadTestRtmpClient extends RTMPClient implements IPendingServiceCal
map.put("instanceId", instanceId);
map.put("count", counterCalls);
calls.put(counterCalls, new CallObject(new Date()));
- invoke("loadTestSyncMessage", new Object[] {"syncMessageToCurrentScopeResult", map, true }, this);
+ invoke("sendMessageToCurrentScope", new Object[] {"syncMessageToCurrentScopeResult", map, true, false }, this);
} else {
System.err.println("Call running " + counterCalls);
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java b/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
index 77f2d6f..f644172 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
@@ -29,6 +29,7 @@ import javax.servlet.ServletContext;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dto.room.Whiteboards;
import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.basic.IClient;
import org.apache.openmeetings.db.entity.room.Invitation;
import org.apache.openmeetings.db.entity.room.StreamClient;
import org.apache.openmeetings.util.ws.IClusterWsMessage;
@@ -45,11 +46,6 @@ public interface IApplication {
String getOmString(String key);
String getOmString(String key, long languageId);
String getOmString(String key, final Locale loc, String... params);
- Client getOmClient(String uid);
- Client getOmClientBySid(String sid);
- Client getOmOnlineClient(String uid);
- List<Client> getOmRoomClients(Long roomId);
- List<Client> getOmClients(Long userId);
String getOmContactsLink();
String getOmInvitationLink(Invitation i);
String urlForActivatePage(PageParameters pp);
@@ -58,11 +54,19 @@ public interface IApplication {
void setXFrameOptions(String xFrameOptions);
void setContentSecurityPolicy(String contentSecurityPolicy);
+ IClient update(IClient c);
+
+ // web client
+ Client getOmClient(String uid);
+ Client getOmClientBySid(String sid);
+ Client getOmOnlineClient(String uid);
+ List<Client> getOmRoomClients(Long roomId);
+ List<Client> getOmClients(Long userId);
+
// stream client
StreamClient updateClient(StreamClient rcl, boolean forceSize);
String getServerId();
Map<String, StreamClient> getStreamClients();
- StreamClient update(StreamClient c);
Set<Long> getActiveRoomIds();
//JPA
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
index 7b9b361..47fa60d 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/server/ISessionManager.java
@@ -22,6 +22,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
+import org.apache.openmeetings.db.entity.basic.IClient;
import org.apache.openmeetings.db.entity.room.StreamClient;
/**
@@ -55,7 +56,7 @@ public interface ISessionManager {
* @param rcm
* @return updated client
*/
- StreamClient update(StreamClient rcm);
+ void update(IClient rcm);
/**
* Remove a client from the session store
@@ -75,16 +76,6 @@ public interface ISessionManager {
*/
List<StreamClient> listByRoom(Long roomId);
- Collection<StreamClient> listByRoomAll(Long roomId);
-
- /**
- * get the current Moderator in this room
- *
- * @param roomId
- * @return
- */
- List<StreamClient> listModeratorByRoom(Long roomId);
-
/**
* returns number of current users recording
*
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
index 98d9251..8d4235a 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
@@ -66,6 +66,8 @@ public class Client implements IClient {
private final String uid;
private final String broadcastId;
private final Type type;
+ private Integer width;
+ private Integer height;
public Stream(String uid, String streamId, String broadcastId, Type type) {
this.streamId = streamId;
@@ -90,6 +92,22 @@ public class Client implements IClient {
return uid;
}
+ public Integer getWidth() {
+ return width;
+ }
+
+ public void setWidth(Integer width) {
+ this.width = width;
+ }
+
+ public Integer getHeight() {
+ return height;
+ }
+
+ public void setHeight(Integer height) {
+ this.height = height;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
@@ -100,18 +118,23 @@ public class Client implements IClient {
@Override
public boolean equals(Object obj) {
- if (this == obj)
+ if (this == obj) {
return true;
- if (obj == null)
+ }
+ if (obj == null) {
return false;
- if (getClass() != obj.getClass())
+ }
+ if (getClass() != obj.getClass()) {
return false;
+ }
Stream other = (Stream) obj;
if (broadcastId == null) {
- if (other.broadcastId != null)
+ if (other.broadcastId != null) {
return false;
- } else if (!broadcastId.equals(other.broadcastId))
+ }
+ } else if (!broadcastId.equals(other.broadcastId)) {
return false;
+ }
return true;
}
@@ -137,6 +160,7 @@ public class Client implements IClient {
private int width = 0;
private int height = 0;
private String serverId = null;
+ private Long recordingId;
public Client(String sessionId, int pageId, Long userId, UserDao dao) {
this.sessionId = sessionId;
@@ -153,8 +177,8 @@ public class Client implements IClient {
this.user = user;
this.connectedSince = new Date();
uid = rcl.getUid();
- sid = rcl.getOwnerSid();
- this.remoteAddress = rcl.getUserip();
+ sid = rcl.getSid();
+ this.remoteAddress = rcl.getRemoteAddress();
}
public String getSessionId() {
@@ -183,15 +207,22 @@ public class Client implements IClient {
return this;
}
+ @Override
public Long getUserId() {
return user.getId();
}
@Override
+ public String getLogin() {
+ return user.getLogin();
+ }
+
+ @Override
public String getUid() {
return uid;
}
+ @Override
public String getSid() {
return sid;
}
@@ -370,6 +401,7 @@ public class Client implements IClient {
return this;
}
+ @Override
public int getWidth() {
return width;
}
@@ -379,6 +411,7 @@ public class Client implements IClient {
return this;
}
+ @Override
public int getHeight() {
return height;
}
@@ -388,6 +421,7 @@ public class Client implements IClient {
return this;
}
+ @Override
public String getRemoteAddress() {
return remoteAddress;
}
@@ -407,33 +441,27 @@ public class Client implements IClient {
}
@Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((uid == null) ? 0 : uid.hashCode());
- return result;
+ public void setRecordingStarted(boolean recordingStarted) {
+ if (recordingStarted) {
+ activities.add(Activity.record);
+ } else {
+ activities.remove(Activity.record);
+ }
}
@Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof Client)) {
- return false;
- }
- Client other = (Client) obj;
- if (uid == null) {
- if (other.uid != null) {
- return false;
- }
- } else if (!uid.equals(other.uid)) {
- return false;
- }
- return true;
+ public Long getRecordingId() {
+ return recordingId;
+ }
+
+ @Override
+ public void setRecordingId(Long recordingId) {
+ this.recordingId = recordingId;
+ }
+
+ @Override
+ public Long getRoomId() {
+ return room == null ? null : room.getId();
}
public JSONObject toJson(boolean self) {
@@ -475,6 +503,36 @@ public class Client implements IClient {
}
@Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((uid == null) ? 0 : uid.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof Client)) {
+ return false;
+ }
+ Client other = (Client) obj;
+ if (uid == null) {
+ if (other.uid != null) {
+ return false;
+ }
+ } else if (!uid.equals(other.uid)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
public String toString() {
return "Client [uid=" + uid + ", sessionId=" + sessionId + ", pageId=" + pageId + ", userId=" + user.getId() + ", room=" + (room == null ? null : room.getId())
+ ", rights=" + rights + ", activities=" + activities + ", connectedSince=" + connectedSince + ", pod = " + pod + "]";
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java
index 0ec52cf..f9817a5 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/IClient.java
@@ -36,5 +36,15 @@ public interface IClient extends IDataProviderEntity {
, sharing
}
String getUid();
+ String getSid();
+ Long getUserId();
+ String getLogin();
+ String getRemoteAddress();
+ Long getRoomId();
+ int getWidth();
+ int getHeight();
+ void setRecordingStarted(boolean recordingStarted);
+ Long getRecordingId();
+ void setRecordingId(Long recordingId);
String getServerId();
}
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
index 1b6de62..95a1cc7 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/StreamClient.java
@@ -35,17 +35,17 @@ public class StreamClient implements IClient {
private int width = 0;
private int height = 0;
private String uid = null;
- private String ownerSid = null;
+ private String sid = null;
private boolean mod = false;
private boolean superMod = false;
private boolean canGiveAudio = false;
private boolean canVideo = false;
private Date connectedSince;
- private String userip;
+ private String remoteAddress;
private int userport;
private Date roomEnter = null;
private String broadCastId = null;
- private String username = "";
+ private String login = "";
private Long userId = null;
private String firstname = "";
private String lastname = "";
@@ -96,6 +96,7 @@ public class StreamClient implements IClient {
}
}
+ @Override
public int getWidth() {
return width;
}
@@ -104,6 +105,7 @@ public class StreamClient implements IClient {
this.width = width;
}
+ @Override
public int getHeight() {
return height;
}
@@ -121,12 +123,13 @@ public class StreamClient implements IClient {
this.uid = uid;
}
- public String getOwnerSid() {
- return ownerSid;
+ @Override
+ public String getSid() {
+ return sid;
}
- public void setOwnerSid(String ownerSid) {
- this.ownerSid = ownerSid;
+ public void setSid(String sid) {
+ this.sid = sid;
}
public boolean isMod() {
@@ -169,12 +172,13 @@ public class StreamClient implements IClient {
this.connectedSince = connectedSince;
}
- public String getUserip() {
- return userip;
+ @Override
+ public String getRemoteAddress() {
+ return remoteAddress;
}
- public void setUserip(String userip) {
- this.userip = userip;
+ public void setRemoteAddress(String remoteAddress) {
+ this.remoteAddress = remoteAddress;
}
public int getUserport() {
@@ -201,14 +205,16 @@ public class StreamClient implements IClient {
this.broadCastId = broadCastId;
}
- public String getUsername() {
- return username;
+ @Override
+ public String getLogin() {
+ return login;
}
- public void setUsername(String username) {
- this.username = username;
+ public void setLogin(String login) {
+ this.login = login;
}
+ @Override
public Long getUserId() {
return userId;
}
@@ -301,6 +307,7 @@ public class StreamClient implements IClient {
return recordingStarted;
}
+ @Override
public void setRecordingStarted(boolean recordingStarted) {
this.recordingStarted = recordingStarted;
}
@@ -329,10 +336,12 @@ public class StreamClient implements IClient {
this.broadcasting = isBroadcasting;
}
+ @Override
public Long getRecordingId() {
return recordingId;
}
+ @Override
public void setRecordingId(Long recordingId) {
this.recordingId = recordingId;
}
@@ -394,6 +403,7 @@ public class StreamClient implements IClient {
this.serverId = serverId;
}
+ @Override
public Long getRoomId() {
return roomId;
}
@@ -408,8 +418,8 @@ public class StreamClient implements IClient {
@Override
public String toString() {
- return "StreamClient [scope=" + scope + ", uid=" + uid + ", ownerSid=" + ownerSid + ", broadCastId="
- + broadCastId + ", username=" + username + ", userId=" + userId + ", avsettings=" + avsettings + ", type=" + type
+ return "StreamClient [scope=" + scope + ", uid=" + uid + ", ownerSid=" + sid + ", broadCastId="
+ + broadCastId + ", login=" + login + ", userId=" + userId + ", avsettings=" + avsettings + ", type=" + type
+ ", isBroadcasting=" + broadcasting + "]";
}
}
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
index 5bbf401..0c3f904 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
@@ -104,7 +104,7 @@ public class ConnectionsPanel extends AdminPanel {
if (_c instanceof StreamClient) {
StreamClient c = (StreamClient)_c;
item.add(new Label("type", "flash"));
- item.add(new Label("login", c.getUsername()));
+ item.add(new Label("login", c.getLogin()));
item.add(new Label("since", c.getConnectedSince()));
item.add(new Label("scope"));
confirm.setEnabled(Client.Type.sharing != c.getType());
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
index 65f5f81..19f7002 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
@@ -89,7 +89,7 @@ public class RoomForm extends AdminBaseForm<Room> {
protected void populateItem(final ListItem<StreamClient> item) {
StreamClient client = item.getModelObject();
item.add(new Label("clientId", "" + client.getId()))
- .add(new Label("clientLogin", "" + client.getUsername()))
+ .add(new Label("clientLogin", "" + client.getLogin()))
.add(new ConfirmableAjaxBorder("clientDelete", getString("80"), getString("833")) {
private static final long serialVersionUID = 1L;
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 445932a..71eac66 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -60,6 +60,7 @@ import org.apache.openmeetings.db.dto.room.Whiteboards;
import org.apache.openmeetings.db.entity.basic.Client;
import org.apache.openmeetings.db.entity.basic.Client.Activity;
import org.apache.openmeetings.db.entity.basic.Client.Pod;
+import org.apache.openmeetings.db.entity.basic.IClient;
import org.apache.openmeetings.db.entity.log.ConferenceLog;
import org.apache.openmeetings.db.entity.record.Recording;
import org.apache.openmeetings.db.entity.room.Invitation;
@@ -367,8 +368,12 @@ public class Application extends AuthenticatedWebApplication implements IApplica
}
@Override
- public StreamClient update(StreamClient c) {
- hazelcast.getMap(STREAM_CLIENT_KEY).put(c.getUid(), c);
+ public IClient update(IClient c) {
+ if (c instanceof StreamClient) {
+ hazelcast.getMap(STREAM_CLIENT_KEY).put(c.getUid(), c);
+ } else {
+ update((Client)c);
+ }
return c;
}
@@ -423,10 +428,10 @@ public class Application extends AuthenticatedWebApplication implements IApplica
if (rcl == null) {
return null;
}
- Client client = getClientBySid(rcl.getOwnerSid());
+ Client client = getClientBySid(rcl.getSid());
if (client == null) {
if (Client.Type.mobile == rcl.getType()) {
- Sessiondata sd = getBean(SessiondataDao.class).check(rcl.getOwnerSid());
+ Sessiondata sd = getBean(SessiondataDao.class).check(rcl.getSid());
UserDao udao = getBean(UserDao.class);
User u = udao.get(sd.getUserId());
rcl = getBean(MobileService.class).create(rcl, u);
@@ -443,7 +448,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
}
//FIXME TODO rights
} else if (client == null && Client.Type.sip == rcl.getType()) {
- rcl.setUsername(SIP_USER_NAME);
+ rcl.setLogin(SIP_USER_NAME);
rcl.setUserId(SIP_USER_ID);
//SipTransport enters the room
User u = new User();
@@ -469,7 +474,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
}
User u = client.getUser();
rcl.setUserId(u.getId());
- rcl.setUsername(u.getLogin());
+ rcl.setLogin(u.getLogin());
rcl.setFirstname(u.getFirstname());
rcl.setLastname(u.getLastname());
rcl.setEmail(u.getAddress() == null ? null : u.getAddress().getEmail());
@@ -635,6 +640,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
public static List<Client> getRoomClients(Long roomId) {
return getRoomClients(roomId, null);
}
+
public static List<Client> getRoomClients(Long roomId, Predicate<Client> filter) {
List<Client> clients = new ArrayList<>();
if (roomId != null) {
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 6c5b450..f29e7d1 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -119,6 +119,7 @@ public class RoomPanel extends BasePanel {
, exclusive
}
private final Room r;
+ private final boolean isInterview;
private final WebMarkupContainer room = new WebMarkupContainer("roomContainer");
private final AbstractDefaultAjaxBehavior roomEnter = new AbstractDefaultAjaxBehavior() {
private static final long serialVersionUID = 1L;
@@ -133,7 +134,7 @@ public class RoomPanel extends BasePanel {
, cp.getRemoteAddress()
, "" + r.getId());
JSONObject options = VideoSettings.getInitJson(cp, "" + r.getId(), getClient().getSid());
- options.put("interview", Room.Type.interview == r.getType());
+ options.put("interview", isInterview);
options.put("showMicStatus", !r.getHiddenElements().contains(RoomElement.MicrophoneStatus));
target.appendJavaScript(String.format("VideoManager.init(%s);", options));
WebSocketHelper.sendRoom(new RoomMessage(r.getId(), getUserId(), RoomMessage.Type.roomEnter));
@@ -203,20 +204,25 @@ public class RoomPanel extends BasePanel {
public RoomPanel(String id, Room r) {
super(id);
this.r = r;
- this.wb = Room.Type.interview == r.getType()
- ? new InterviewWbPanel("whiteboard", this)
- : new WbPanel("whiteboard", this);
+ this.isInterview = Room.Type.interview == r.getType();
+ this.wb = isInterview ? new InterviewWbPanel("whiteboard", this) : new WbPanel("whiteboard", this);
}
private void initVideos(AjaxRequestTarget target) {
StringBuilder sb = new StringBuilder();
+ boolean hasStreams = false;
+ Client _c = getClient();
for (Client c: getRoomClients(getRoom().getId()) ) {
- boolean self = getClient().getUid().equals(c.getUid());
+ boolean self = _c.getUid().equals(c.getUid());
for (Client.Stream s : c.getStreams()) {
JSONObject jo = videoJson(c, self, c.getSid(), getBean(ISessionManager.class), s.getUid());
sb.append(String.format("VideoManager.play(%s);", jo));
+ hasStreams = true;
}
}
+ if (isInterview && recordingUser == null && hasStreams && _c.hasRight(Right.moderator)) {
+ sb.append("WbArea.setRecStartEnabled(true);");
+ }
if (!Strings.isEmpty(sb)) {
target.appendJavaScript(sb);
}
@@ -232,7 +238,7 @@ public class RoomPanel extends BasePanel {
room.add(menu = new RoomMenuPanel("menu", this));
room.add(AttributeModifier.append("data-room-id", r.getId()));
- if (Room.Type.interview == r.getType()) {
+ if (isInterview) {
room.add(new WebMarkupContainer("wb-area").add(wb));
} else {
Droppable<FileItem> wbArea = new Droppable<FileItem>("wb-area") {
@@ -487,6 +493,9 @@ public class RoomPanel extends BasePanel {
if (_c.getSid().equals(c.getSid())) {
update(c.addStream(uid, streamId, broadcastId, type));
}
+ if (isInterview && recordingUser == null && _c.hasRight(Right.moderator)) {
+ handler.appendJavaScript("WbArea.setRecStartEnabled(true);");
+ }
}
break;
case closeStream:
@@ -497,10 +506,21 @@ public class RoomPanel extends BasePanel {
log.error("Not existing user in closeStream {} !!!!", obj);
return;
}
- if (getClient().getUid().equals(c.getUid())) {
+ Client _c = getClient();
+ if (_c.getUid().equals(c.getUid())) {
update(c.removeStream(obj.optString("broadcastId")));
}
handler.appendJavaScript(String.format("VideoManager.close('%s');", obj.getString("uid")));
+ if (isInterview && recordingUser == null && _c.hasRight(Right.moderator)) {
+ boolean hasStreams = false;
+ for (Client cl : getRoomClients(r.getId())) {
+ if (!cl.getStreams().isEmpty()) {
+ hasStreams = true;
+ break;
+ }
+ }
+ handler.appendJavaScript(String.format("WbArea.setRecStartEnabled(%s);", hasStreams));
+ }
}
break;
case roomEnter:
@@ -660,7 +680,7 @@ public class RoomPanel extends BasePanel {
super.renderHead(response);
response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(RoomPanel.class, "jquery.dialogextend.js"))));
response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(RoomPanel.class, "room.js"))));
- if (Room.Type.interview == r.getType()) {
+ if (isInterview) {
response.render(JavaScriptHeaderItem.forReference(INTERVIEWWB_JS_REFERENCE));
} else {
response.render(JavaScriptHeaderItem.forReference(WB_JS_REFERENCE));
@@ -769,7 +789,7 @@ public class RoomPanel extends BasePanel {
public boolean screenShareAllowed() {
Room r = getRoom();
- return Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing)
+ return !isInterview && !r.isHidden(RoomElement.ScreenSharing)
&& r.isAllowRecording() && getClient().hasRight(Right.share)
&& sharingUser == null;
}
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/AbstractWbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/AbstractWbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/AbstractWbPanel.java
index c25eaa4..bd0aba7 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/AbstractWbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/AbstractWbPanel.java
@@ -18,17 +18,34 @@
*/
package org.apache.openmeetings.web.room.wb;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.openmeetings.web.room.wb.WbWebSocketHelper.PARAM_OBJ;
+import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
+import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
+
+import java.io.IOException;
+
import org.apache.openmeetings.db.entity.file.FileItem;
import org.apache.openmeetings.web.room.RoomPanel;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
+import org.apache.wicket.markup.head.PriorityHeaderItem;
import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.util.string.StringValue;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+
+import com.github.openjson.JSONObject;
public abstract class AbstractWbPanel extends Panel {
private static final long serialVersionUID = 1L;
+ private static final Logger log = Red5LoggerFactory.getLogger(AbstractWbPanel.class, webAppRootKey);
+ public static final String FUNC_ACTION = "wbAction";
+ public static final String PARAM_ACTION = "action";
protected static final String ROLE_NONE = "none";
protected final RoomPanel rp;
protected boolean inited = false;
@@ -43,12 +60,38 @@ public abstract class AbstractWbPanel extends Panel {
inited = true;
}
};
+ private final AbstractDefaultAjaxBehavior wbAction = new AbstractDefaultAjaxBehavior() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
+ updateWbActionAttributes(attributes);
+ }
+
+ @Override
+ protected void respond(AjaxRequestTarget target) {
+ if (!inited) {
+ return;
+ }
+ if (!inited) {
+ return;
+ }
+ try {
+ WbAction a = WbAction.valueOf(getRequest().getRequestParameters().getParameterValue(PARAM_ACTION).toString());
+ StringValue sv = getRequest().getRequestParameters().getParameterValue(PARAM_OBJ);
+ JSONObject obj = sv.isEmpty() ? new JSONObject() : new JSONObject(sv.toString());
+ processWbAction(a, obj, target);
+ } catch (Exception e) {
+ log.error("Unexpected error while processing wbAction", e);
+ }
+ }
+ };
public AbstractWbPanel(String id, RoomPanel rp) {
super(id);
this.rp = rp;
setOutputMarkupId(true);
- add(wbLoad);
+ add(wbLoad, wbAction);
}
public AbstractWbPanel update(IPartialPageRequestHandler handler) {
@@ -60,15 +103,34 @@ public abstract class AbstractWbPanel extends Panel {
protected abstract String getRole();
- void internalWbLoad(StringBuilder sb) {
- }
+ /**
+ * Internal method to perform JS actions on WB load
+ *
+ * @param sb - {@link StringBuilder} to put JS calls
+ */
+ void internalWbLoad(StringBuilder sb) {}
- public void sendFileToWb(final FileItem fi, boolean clean) {
- }
+ /**
+ * This method being called when file is dropped to WB
+ *
+ * @param fi - File being dropped
+ * @param clean - should WB be cleaned up
+ */
+ public void sendFileToWb(final FileItem fi, boolean clean) {}
+
+ /**
+ * This method allows to set additional attributes to wbAction
+ *
+ * @param attributes - attributes to set
+ */
+ protected void updateWbActionAttributes(AjaxRequestAttributes attributes) {}
+
+ protected abstract void processWbAction(WbAction a, JSONObject obj, AjaxRequestTarget target) throws IOException;
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(OnDomReadyHeaderItem.forScript(wbLoad.getCallbackScript()));
+ response.render(new PriorityHeaderItem(getNamedFunction(FUNC_ACTION, wbAction, explicit(PARAM_ACTION), explicit(PARAM_OBJ))));
}
}
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/InterviewWbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/InterviewWbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/InterviewWbPanel.java
index cf6cd5c..a24fa41 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/InterviewWbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/InterviewWbPanel.java
@@ -18,12 +18,23 @@
*/
package org.apache.openmeetings.web.room.wb;
+import static org.apache.openmeetings.web.app.Application.getBean;
+
+import java.io.IOException;
+
+import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
+import org.apache.openmeetings.db.entity.basic.Client;
import org.apache.openmeetings.db.entity.file.FileItem;
+import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.room.Room.Right;
import org.apache.openmeetings.web.room.RoomPanel;
+import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.request.resource.JavaScriptResourceReference;
import org.apache.wicket.request.resource.ResourceReference;
+import com.github.openjson.JSONObject;
+
public class InterviewWbPanel extends AbstractWbPanel {
private static final long serialVersionUID = 1L;
public final static ResourceReference INTERVIEWWB_JS_REFERENCE = new JavaScriptResourceReference(WbPanel.class, "interviewwb.js");
@@ -38,6 +49,21 @@ public class InterviewWbPanel extends AbstractWbPanel {
}
@Override
- public void sendFileToWb(final FileItem fi, boolean clean) {
+ public void sendFileToWb(final FileItem fi, boolean clean) {}
+
+ @Override
+ protected void processWbAction(WbAction a, JSONObject obj, AjaxRequestTarget target) throws IOException {
+ Client c = rp.getClient();
+ if (c.hasRight(Room.Right.moderator)) {
+ switch (a) {
+ case startRecording:
+ if (getBean(ISessionManager.class).getRecordingCount(c.getRoomId()) < 1) {
+ getBean(ScopeApplicationAdapter.class).startInterviewRecording(c);
+ }
+ break;
+ default:
+ //no-op
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbAction.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbAction.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbAction.java
index 5ef5bfd..09e238c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbAction.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbAction.java
@@ -33,4 +33,6 @@ public enum WbAction {
, undo
, setSize
, downloadPdf
+ , startRecording
+ , stopRecording
}
http://git-wip-us.apache.org/repos/asf/openmeetings/blob/5fd782fc/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
index 41eb7e4..17ac2ac 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbPanel.java
@@ -21,12 +21,9 @@ package org.apache.openmeetings.web.room.wb;
import static org.apache.openmeetings.db.dto.room.Whiteboard.ITEMS_KEY;
import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
import static org.apache.openmeetings.web.app.Application.getBean;
-import static org.apache.openmeetings.web.room.wb.WbWebSocketHelper.PARAM_OBJ;
import static org.apache.openmeetings.web.room.wb.WbWebSocketHelper.getObjWbJson;
import static org.apache.openmeetings.web.room.wb.WbWebSocketHelper.getWbJson;
-import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
import static org.apache.wicket.AttributeModifier.append;
-import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
@@ -74,19 +71,16 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
-import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes.Method;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
-import org.apache.wicket.markup.head.PriorityHeaderItem;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.request.resource.JavaScriptResourceReference;
import org.apache.wicket.request.resource.ResourceReference;
-import org.apache.wicket.util.string.StringValue;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
@@ -102,233 +96,11 @@ public class WbPanel extends AbstractWbPanel {
private static final int DEFAULT_WIDTH = 640;
private static final int DEFAULT_HEIGHT = 480;
private static final int UNDO_SIZE = 20;
- public static final String FUNC_ACTION = "wbAction";
- public static final String PARAM_ACTION = "action";
public final static ResourceReference WB_JS_REFERENCE = new JavaScriptResourceReference(WbPanel.class, "wb.js");
private final static ResourceReference FABRIC_JS_REFERENCE = new JavaScriptResourceReference(WbPanel.class, "fabric.js");
private final Long roomId;
private long wb2save = -1;
private final Map<Long, Deque<UndoObject>> undoList = new HashMap<>();
- private final AbstractDefaultAjaxBehavior wbAction = new AbstractDefaultAjaxBehavior() {
- private static final long serialVersionUID = 1L;
-
- @Override
- protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
- attributes.setMethod(Method.POST);
- }
-
- @Override
- protected void respond(AjaxRequestTarget target) {
- if (!inited) {
- return;
- }
- try {
- WbAction a = WbAction.valueOf(getRequest().getRequestParameters().getParameterValue(PARAM_ACTION).toString());
- StringValue sv = getRequest().getRequestParameters().getParameterValue(PARAM_OBJ);
- JSONObject obj = sv.isEmpty() ? new JSONObject() : new JSONObject(sv.toString());
- if (WbAction.createObj == a || WbAction.modifyObj == a) {
- JSONObject o = obj.optJSONObject("obj");
- if (o != null && "pointer".equals(o.getString("type"))) {
- sendWbOthers(a, obj);
- return;
- }
- }
-
- Client c = rp.getClient();
- if (WbAction.downloadPdf == a) {
- boolean moder = c.hasRight(Room.Right.moderator);
- Room r = rp.getRoom();
- if ((moder && !r.isHidden(RoomElement.ActionMenu)) || (!moder && r.isAllowUserQuestions())) {
- try (PDDocument doc = new PDDocument()) {
- JSONArray arr = obj.getJSONArray("slides");
- for (int i = 0; i < arr.length(); ++i) {
- String base64Image = arr.getString(i).split(",")[1];
- byte[] bb = Base64.decodeBase64(base64Image);
- BufferedImage img = ImageIO.read(new ByteArrayInputStream(bb));
- float width = img.getWidth();
- float height = img.getHeight();
- PDPage page = new PDPage(new PDRectangle(width, height));
- PDImageXObject pdImageXObject = LosslessFactory.createFromImage(doc, img);
- try (PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.APPEND, false)) {
- contentStream.drawImage(pdImageXObject, 0, 0, width, height);
- }
- doc.addPage(page);
- }
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- doc.save(baos);
- rp.startDownload(target, baos.toByteArray());
- }
- }
- return;
- }
- //presenter-right
- if (c.hasRight(Right.presenter)) {
- switch (a) {
- case createWb:
- {
- Whiteboard wb = WhiteboardCache.add(roomId, c.getUser().getLanguageId());
- sendWbAll(WbAction.createWb, getAddWbJson(wb));
- }
- break;
- case removeWb:
- {
- long _id = obj.optLong("wbId", -1);
- Long id = _id < 0 ? null : _id;
- WhiteboardCache.remove(roomId, id);
- sendWbAll(WbAction.removeWb, obj);
- }
- break;
- case activateWb:
- {
- long _id = obj.optLong("wbId", -1);
- if (_id > -1) {
- WhiteboardCache.activate(roomId, _id);
- sendWbAll(WbAction.activateWb, obj);
- }
- }
- break;
- case setSlide:
- {
- Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
- wb.setSlide(obj.optInt("slide", 0));
- WhiteboardCache.update(roomId, wb);
- sendWbOthers(WbAction.setSlide, obj);
- }
- break;
- case clearAll:
- {
- clearAll(roomId, obj.getLong("wbId"));
- }
- break;
- case setSize:
- {
- Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
- wb.setZoom(obj.getDouble("zoom"));
- wb.setZoomMode(ZoomMode.valueOf(obj.getString("zoomMode")));
- WhiteboardCache.update(roomId, wb);
- sendWbOthers(WbAction.setSize, getAddWbJson(wb));
- //TODO scroll????
- }
- break;
- default:
- break;
- }
- }
- //wb-right
- if (c.hasRight(Right.presenter) || c.hasRight(Right.whiteBoard)) {
- switch (a) {
- case createObj:
- {
- Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
- JSONObject o = obj.getJSONObject("obj");
- wb.put(o.getString("uid"), o);
- WhiteboardCache.update(roomId, wb);
- addUndo(wb.getId(), new UndoObject(UndoObject.Type.add, o));
- sendWbOthers(WbAction.createObj, obj);
- }
- break;
- case modifyObj:
- {
- Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
- JSONArray arr = obj.getJSONArray("obj");
- JSONArray undo = new JSONArray();
- for (int i = 0; i < arr.length(); ++i) {
- JSONObject _o = arr.getJSONObject(i);
- String uid = _o.getString("uid");
- undo.put(wb.get(uid));
- wb.put(uid, _o);
- }
- if (arr.length() != 0) {
- WhiteboardCache.update(roomId, wb);
- addUndo(wb.getId(), new UndoObject(UndoObject.Type.modify, undo));
- }
- sendWbOthers(WbAction.modifyObj, obj);
- }
- break;
- case deleteObj:
- {
- Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
- JSONArray arr = obj.getJSONArray("obj");
- JSONArray undo = new JSONArray();
- for (int i = 0; i < arr.length(); ++i) {
- JSONObject _o = arr.getJSONObject(i);
- JSONObject u = wb.remove(_o.getString("uid"));
- if (u != null) {
- undo.put(u);
- }
- }
- if (undo.length() != 0) {
- WhiteboardCache.update(roomId, wb);
- addUndo(wb.getId(), new UndoObject(UndoObject.Type.remove, undo));
- }
- sendWbAll(WbAction.deleteObj, obj);
- }
- break;
- case clearSlide:
- {
- Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
- JSONArray arr = wb.clearSlide(obj.getInt("slide"));
- if (arr.length() != 0) {
- WhiteboardCache.update(roomId, wb);
- addUndo(wb.getId(), new UndoObject(UndoObject.Type.remove, arr));
- }
- sendWbAll(WbAction.clearSlide, obj);
- }
- break;
- case save:
- wb2save = obj.getLong("wbId");
- fileName.open(target);
- break;
- case undo:
- {
- Long wbId = obj.getLong("wbId");
- UndoObject uo = getUndo(wbId);
- if (uo != null) {
- Whiteboard wb = WhiteboardCache.get(roomId).get(wbId);
- switch (uo.getType()) {
- case add:
- {
- JSONObject o = new JSONObject(uo.getObject());
- wb.remove(o.getString("uid"));
- WhiteboardCache.update(roomId, wb);
- sendWbAll(WbAction.deleteObj, obj.put("obj", new JSONArray().put(o)));
- }
- break;
- case remove:
- {
- JSONArray arr = new JSONArray(uo.getObject());
- for (int i = 0; i < arr.length(); ++i) {
- JSONObject o = arr.getJSONObject(i);
- wb.put(o.getString("uid"), o);
- }
- WhiteboardCache.update(roomId, wb);
- sendWbAll(WbAction.createObj, obj.put("obj", new JSONArray(uo.getObject())));
- }
- break;
- case modify:
- {
- JSONArray arr = new JSONArray(uo.getObject());
- for (int i = 0; i < arr.length(); ++i) {
- JSONObject o = arr.getJSONObject(i);
- wb.put(o.getString("uid"), o);
- }
- WhiteboardCache.update(roomId, wb);
- sendWbAll(WbAction.modifyObj, obj.put("obj", arr));
- }
- break;
- }
- }
- }
- break;
- default:
- break;
- }
- }
- } catch (Exception e) {
- log.error("Unexpected error while processing wbAction", e);
- }
- }
- };
private final NameDialog fileName = new NameDialog("filename") {
private static final long serialVersionUID = 1L;
@@ -382,7 +154,6 @@ public class WbPanel extends AbstractWbPanel {
, new AttributeAppender("data-image", item.getModelObject()).setSeparator(""));
}
}, fileName);
- add(wbAction);
}
}
@@ -390,7 +161,6 @@ public class WbPanel extends AbstractWbPanel {
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(JavaScriptHeaderItem.forReference(FABRIC_JS_REFERENCE));
- response.render(new PriorityHeaderItem(getNamedFunction(FUNC_ACTION, wbAction, explicit(PARAM_ACTION), explicit(PARAM_OBJ))));
}
@Override
@@ -413,6 +183,213 @@ public class WbPanel extends AbstractWbPanel {
}
}
+ @Override
+ protected void updateWbActionAttributes(AjaxRequestAttributes attributes) {
+ attributes.setMethod(Method.POST);
+ }
+
+ @Override
+ protected void processWbAction(WbAction a, JSONObject obj, AjaxRequestTarget target) throws IOException {
+ if (WbAction.createObj == a || WbAction.modifyObj == a) {
+ JSONObject o = obj.optJSONObject("obj");
+ if (o != null && "pointer".equals(o.getString("type"))) {
+ sendWbOthers(a, obj);
+ return;
+ }
+ }
+
+ Client c = rp.getClient();
+ if (WbAction.downloadPdf == a) {
+ boolean moder = c.hasRight(Room.Right.moderator);
+ Room r = rp.getRoom();
+ if ((moder && !r.isHidden(RoomElement.ActionMenu)) || (!moder && r.isAllowUserQuestions())) {
+ try (PDDocument doc = new PDDocument()) {
+ JSONArray arr = obj.getJSONArray("slides");
+ for (int i = 0; i < arr.length(); ++i) {
+ String base64Image = arr.getString(i).split(",")[1];
+ byte[] bb = Base64.decodeBase64(base64Image);
+ BufferedImage img = ImageIO.read(new ByteArrayInputStream(bb));
+ float width = img.getWidth();
+ float height = img.getHeight();
+ PDPage page = new PDPage(new PDRectangle(width, height));
+ PDImageXObject pdImageXObject = LosslessFactory.createFromImage(doc, img);
+ try (PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.APPEND, false)) {
+ contentStream.drawImage(pdImageXObject, 0, 0, width, height);
+ }
+ doc.addPage(page);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ doc.save(baos);
+ rp.startDownload(target, baos.toByteArray());
+ }
+ }
+ return;
+ }
+ //presenter-right
+ if (c.hasRight(Right.presenter)) {
+ switch (a) {
+ case createWb:
+ {
+ Whiteboard wb = WhiteboardCache.add(roomId, c.getUser().getLanguageId());
+ sendWbAll(WbAction.createWb, getAddWbJson(wb));
+ }
+ break;
+ case removeWb:
+ {
+ long _id = obj.optLong("wbId", -1);
+ Long id = _id < 0 ? null : _id;
+ WhiteboardCache.remove(roomId, id);
+ sendWbAll(WbAction.removeWb, obj);
+ }
+ break;
+ case activateWb:
+ {
+ long _id = obj.optLong("wbId", -1);
+ if (_id > -1) {
+ WhiteboardCache.activate(roomId, _id);
+ sendWbAll(WbAction.activateWb, obj);
+ }
+ }
+ break;
+ case setSlide:
+ {
+ Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
+ wb.setSlide(obj.optInt("slide", 0));
+ WhiteboardCache.update(roomId, wb);
+ sendWbOthers(WbAction.setSlide, obj);
+ }
+ break;
+ case clearAll:
+ {
+ clearAll(roomId, obj.getLong("wbId"));
+ }
+ break;
+ case setSize:
+ {
+ Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
+ wb.setZoom(obj.getDouble("zoom"));
+ wb.setZoomMode(ZoomMode.valueOf(obj.getString("zoomMode")));
+ WhiteboardCache.update(roomId, wb);
+ sendWbOthers(WbAction.setSize, getAddWbJson(wb));
+ //TODO scroll????
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ //wb-right
+ if (c.hasRight(Right.presenter) || c.hasRight(Right.whiteBoard)) {
+ switch (a) {
+ case createObj:
+ {
+ Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
+ JSONObject o = obj.getJSONObject("obj");
+ wb.put(o.getString("uid"), o);
+ WhiteboardCache.update(roomId, wb);
+ addUndo(wb.getId(), new UndoObject(UndoObject.Type.add, o));
+ sendWbOthers(WbAction.createObj, obj);
+ }
+ break;
+ case modifyObj:
+ {
+ Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
+ JSONArray arr = obj.getJSONArray("obj");
+ JSONArray undo = new JSONArray();
+ for (int i = 0; i < arr.length(); ++i) {
+ JSONObject _o = arr.getJSONObject(i);
+ String uid = _o.getString("uid");
+ undo.put(wb.get(uid));
+ wb.put(uid, _o);
+ }
+ if (arr.length() != 0) {
+ WhiteboardCache.update(roomId, wb);
+ addUndo(wb.getId(), new UndoObject(UndoObject.Type.modify, undo));
+ }
+ sendWbOthers(WbAction.modifyObj, obj);
+ }
+ break;
+ case deleteObj:
+ {
+ Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
+ JSONArray arr = obj.getJSONArray("obj");
+ JSONArray undo = new JSONArray();
+ for (int i = 0; i < arr.length(); ++i) {
+ JSONObject _o = arr.getJSONObject(i);
+ JSONObject u = wb.remove(_o.getString("uid"));
+ if (u != null) {
+ undo.put(u);
+ }
+ }
+ if (undo.length() != 0) {
+ WhiteboardCache.update(roomId, wb);
+ addUndo(wb.getId(), new UndoObject(UndoObject.Type.remove, undo));
+ }
+ sendWbAll(WbAction.deleteObj, obj);
+ }
+ break;
+ case clearSlide:
+ {
+ Whiteboard wb = WhiteboardCache.get(roomId).get(obj.getLong("wbId"));
+ JSONArray arr = wb.clearSlide(obj.getInt("slide"));
+ if (arr.length() != 0) {
+ WhiteboardCache.update(roomId, wb);
+ addUndo(wb.getId(), new UndoObject(UndoObject.Type.remove, arr));
+ }
+ sendWbAll(WbAction.clearSlide, obj);
+ }
+ break;
+ case save:
+ wb2save = obj.getLong("wbId");
+ fileName.open(target);
+ break;
+ case undo:
+ {
+ Long wbId = obj.getLong("wbId");
+ UndoObject uo = getUndo(wbId);
+ if (uo != null) {
+ Whiteboard wb = WhiteboardCache.get(roomId).get(wbId);
+ switch (uo.getType()) {
+ case add:
+ {
+ JSONObject o = new JSONObject(uo.getObject());
+ wb.remove(o.getString("uid"));
+ WhiteboardCache.update(roomId, wb);
+ sendWbAll(WbAction.deleteObj, obj.put("obj", new JSONArray().put(o)));
+ }
+ break;
+ case remove:
+ {
+ JSONArray arr = new JSONArray(uo.getObject());
+ for (int i = 0; i < arr.length(); ++i) {
+ JSONObject o = arr.getJSONObject(i);
+ wb.put(o.getString("uid"), o);
+ }
+ WhiteboardCache.update(roomId, wb);
+ sendWbAll(WbAction.createObj, obj.put("obj", new JSONArray(uo.getObject())));
+ }
+ break;
+ case modify:
+ {
+ JSONArray arr = new JSONArray(uo.getObject());
+ for (int i = 0; i < arr.length(); ++i) {
+ JSONObject o = arr.getJSONObject(i);
+ wb.put(o.getString("uid"), o);
+ }
+ WhiteboardCache.update(roomId, wb);
+ sendWbAll(WbAction.modifyObj, obj.put("obj", arr));
+ }
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
private static JSONObject getAddWbJson(Whiteboard wb) {
return new JSONObject().put("wbId", wb.getId())
.put("name", wb.getName())