change initialization order.
separate user list
initialization data comes from coweb moderator
--- a/.classpath Mon Jan 14 16:00:07 2013 +0100
+++ b/.classpath Mon Feb 11 10:34:23 2013 +0100
@@ -46,5 +46,7 @@
<attribute name="owner.project.facets" value="java"/>
</attributes>
</classpathentry>
+ <classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.1.2/jackson-core-2.1.2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.1.2/jackson-databind-2.1.2.jar"/>
<classpathentry kind="output" path="server/target/classes"/>
</classpath>
--- a/.settings/.jsdtscope Mon Jan 14 16:00:07 2013 +0100
+++ b/.settings/.jsdtscope Mon Feb 11 10:34:23 2013 +0100
@@ -8,5 +8,6 @@
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.FireFoxBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>
--- a/server/pom.xml Mon Jan 14 16:00:07 2013 +0100
+++ b/server/pom.xml Mon Feb 11 10:34:23 2013 +0100
@@ -7,11 +7,13 @@
<version>0.1</version>
<packaging>war</packaging>
- <properties>
+ <properties>
<coweb-version>1.0</coweb-version>
<cowebx-version>0.8.4</cowebx-version>
<jersey-version>1.16</jersey-version>
<spring-version>3.1.3.RELEASE</spring-version>
+ <!--jetty-version>9.0.0.M4</jetty-version-->
+ <jetty-version>8.1.8.v20121106</jetty-version>
<junit-version>4.10</junit-version>
<thymeleaf-version>2.0.14</thymeleaf-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -33,7 +35,7 @@
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
- <version>8.1.8.v20121106</version>
+ <version>${jetty-version}</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webAppConfig>
--- a/server/src/main/java/org/iri_research/renkan/coweb/RenkanSessionModerator.java Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/RenkanSessionModerator.java Mon Feb 11 10:34:23 2013 +0100
@@ -1,25 +1,143 @@
package org.iri_research.renkan.coweb;
-//import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
+import javax.inject.Inject;
import javax.inject.Named;
import org.coweb.DefaultSessionModerator;
import org.iri_research.renkan.coweb.event.ISyncEventManager;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.RenkanSessionModeratorState;
+import org.iri_research.renkan.models.RosterUser;
+import org.iri_research.renkan.repositories.ProjectsRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
-//import javax.inject.Inject;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
@Named
public class RenkanSessionModerator extends DefaultSessionModerator {
private final Logger logger = LoggerFactory.getLogger(RenkanSessionModerator.class);
+
+ @Inject
+ private ProjectsRepository projectsRepository;
+
+
+ public ProjectsRepository getProjectsRepository() {
+ if(this.projectsRepository == null) {
+ ApplicationContext context = SpringConfigurer.getInstance().getApplicationContext();
+ this.projectsRepository = (ProjectsRepository)context.getBean("projectsRepository");
+ }
+ return projectsRepository;
+ }
+
+ @Override
+ public synchronized boolean canClientJoinSession(String clientId, Map<String,Object> userDefined) {
+ this.logger.debug("canClientJoinSession: " + clientId + " , " + (userDefined==null?"null":userDefined.toString()));
+
+ if(RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().containsKey(clientId)) {
+ this.logger.warn("Client id already declared in user activation map: " + clientId);
+ }
+
+ String projectId = (String)userDefined.get("project_id");
+
+ if(projectId == null) {
+ return false;
+ }
+
+ RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().put(clientId, projectId);
+ return true;
+ }
+
+ private synchronized void activateProject(String clientId) {
+
+ if(!RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().containsKey(clientId)) {
+ this.logger.warn("Client id not declared in user activation map: " + clientId);
+ return;
+ }
+ String project_id = RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().get(clientId);
+ if(project_id == null) {
+ this.logger.warn("Null project id for client id in user activation map: " + clientId);
+ return;
+ }
+
+ List<String> user_list = RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().get(project_id);
+ if(user_list == null) {
+ user_list = new ArrayList<String>();
+ RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().put(project_id, user_list);
+ }
+
+ if(!user_list.contains(clientId)) {
+ user_list.add(clientId);
+ }
+
+ }
+
+ @Override
+ public synchronized void onClientJoinSession(String clientId) {
+
+ this.logger.debug("onClientJoinSession: " + clientId);
+
+ this.activateProject(clientId);
+
+ }
+
+ @Override
+ public synchronized void onClientLeaveSession(String clientId) {
+
+ this.logger.debug("onClientLeaveSession: " + clientId);
+
+ String project_id = RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().get(clientId);
+
+ RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().remove(clientId);
+ if(project_id == null) {
+ this.logger.warn("Leaving client have no associated project: " + clientId);
+ return;
+ }
+
+ List<String> user_list = RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().get(project_id);
+ if(user_list == null) {
+ this.logger.warn("Leaving client have associated project but no project list : " + clientId + ", " + project_id);
+ return;
+ }
+
+ if(!user_list.remove(clientId)) {
+ this.logger.warn("Leaving client have associated project but not in project list : " + clientId + ", " + project_id);
+ return;
+ }
+
+ if(user_list.isEmpty()) {
+ this.logger.debug("Leaving client, project list empty, removing from active projects: " + clientId + ", " + project_id);
+ RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().remove(project_id);
+ }
+
+ List<RosterUser> r_user_list = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(project_id);
+ if(r_user_list == null) {
+ this.logger.warn("Leaving client have associated project but no user list : " + clientId + ", " + project_id);
+ return;
+ }
+ for (RosterUser rosterUser : r_user_list) {
+ if( rosterUser.getClient_id().equals(clientId)) {
+ r_user_list.remove(rosterUser);
+ }
+ }
+ if(r_user_list.isEmpty()) {
+ this.logger.debug("Leaving client, user list empty, removing from active projects: " + clientId + ", " + project_id);
+ RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().remove(project_id);
+ }
+
+ }
+
@SuppressWarnings("unchecked")
@Override
- public void onSync(String clientId, Map<String, Object> data) {
+ public synchronized void onSync(String clientId, Map<String, Object> data) {
this.logger.debug("Debugging onSync client id: " + clientId);
this.logger.debug("Debugging onSync: " + data.toString());
@@ -57,7 +175,7 @@
try {
ISyncEventManager<?, ?> eventManager = (ISyncEventManager<?, ?>)context.getBean(beanName);
logger.debug("Debugging on Sync : dispatch to " + beanName);
- eventManager.dispatchEvent(data);
+ eventManager.dispatchEvent(clientId, data);
}
catch(Throwable e) {
this.logger.error(String.format("onSync EventManagerClass %s not found : error %s : %s", sync_type, e.toString(), e.getMessage()));
@@ -65,4 +183,44 @@
}
+ @Override
+ public Map<String, Object> getLateJoinState() {
+ this.logger.debug("getLateJoinState");
+
+ Map<String, Object> res = super.getLateJoinState();
+ ObjectMapper mapper = new ObjectMapper();
+
+ for (String clientId : RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().keySet()) {
+ this.activateProject(clientId);
+ }
+
+ this.logger.debug("getLateJoinState : Project activated");
+
+ for (String project_id : RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().keySet()) {
+
+ Project p = this.getProjectsRepository().findOne(project_id);
+ if (p != null) {
+ try {
+ res.put("renkan_"+project_id, mapper.writeValueAsString(p));
+ } catch (JsonProcessingException e) {
+ this.logger.error("Error when deserializing project " + project_id, e);
+ }
+ }
+
+ String user_res = "[]";
+ if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(project_id)) {
+ try {
+ user_res = mapper.writeValueAsString(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(project_id));
+ } catch (JsonProcessingException e) {
+ this.logger.error("Error when deserializing user list " + project_id, e);
+ }
+ }
+ res.put("users_"+project_id, user_res);
+ }
+
+
+ this.logger.debug("getLateJoinState res : " + res.toString());
+ return res;
+ }
+
}
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/AbstractSyncEventManager.java Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/AbstractSyncEventManager.java Mon Feb 11 10:34:23 2013 +0100
@@ -23,7 +23,7 @@
import com.mongodb.WriteResult;
-public abstract class AbstractSyncEventManager<T extends IRenkanModel<ID>, ID extends Serializable> implements ISyncEventManager<T,ID> {
+public abstract class AbstractSyncEventManager<T extends IRenkanModel<ID>, ID extends Serializable> implements IPersistedSyncEventManager<T,ID> {
private final Logger logger = LoggerFactory.getLogger(AbstractSyncEventManager.class);
@@ -42,23 +42,23 @@
public abstract IRenkanRepository<T, ID> getObjectRepository();
@Override
- public void dispatchEvent(Map<String, Object> data) {
+ public void dispatchEvent(String clientId, Map<String, Object> data) {
this.saveSyncEvent(data);
String eventType = (String) data.get("type");
if("null".equalsIgnoreCase(eventType)) {
- this.nullOperation(data);
+ this.nullOperation(null, data);
}
else if ("update".equalsIgnoreCase(eventType)) {
- this.update(data);
+ this.update(clientId, data);
}
else if ("insert".equalsIgnoreCase(eventType)) {
- this.insert(data);
+ this.insert(clientId, data);
}
else if("delete".equalsIgnoreCase(eventType)) {
- this.delete(data);
+ this.delete(clientId, data);
}
else {
logger.warn(String.format("dispatchEvent : eventType unknown %s", eventType));
@@ -107,7 +107,7 @@
protected abstract List<T> getObjectList(Project project);
@Override
- public void update(Map<String, Object> data) {
+ public void update(String clientId, Map<String, Object> data) {
this.logger.debug("AbstractSyncEventManager: update " + this.getClass().getName());
@@ -149,10 +149,10 @@
}
@Override
- public abstract void insert(Map<String, Object> data);
+ public abstract void insert(String clientId, Map<String, Object> data);
@Override
- public void delete(Map<String, Object> data) {
+ public void delete(String clientId, Map<String, Object> data) {
@SuppressWarnings("unchecked")
Map<String, Object> values = (Map<String, Object>) data.get("value");
@@ -206,7 +206,7 @@
}
@Override
- public abstract void nullOperation(Map<String, Object> data);
+ public abstract void nullOperation(String clientId, Map<String, Object> data);
}
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/EdgeSyncEventManager.java Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/EdgeSyncEventManager.java Mon Feb 11 10:34:23 2013 +0100
@@ -52,7 +52,7 @@
@Override
- public void insert(Map<String, Object> data) {
+ public void insert(String clientId, Map<String, Object> data) {
// get project
this.logger.debug("EdgeSyncEventManager: insert Edge");
@@ -106,7 +106,7 @@
}
@Override
- public void nullOperation(Map<String, Object> data) {
+ public void nullOperation(String clientId, Map<String, Object> data) {
this.logger.debug("nullOperation: NOP");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/IPersistedSyncEventManager.java Mon Feb 11 10:34:23 2013 +0100
@@ -0,0 +1,13 @@
+package org.iri_research.renkan.coweb.event;
+
+import java.io.Serializable;
+
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+
+public interface IPersistedSyncEventManager<T, ID extends Serializable> extends ISyncEventManager<T, ID> {
+
+ public ProjectsRepository getProjectsRepository();
+ public IRenkanRepository<T,ID> getObjectRepository();
+
+}
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/ISyncEventManager.java Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/ISyncEventManager.java Mon Feb 11 10:34:23 2013 +0100
@@ -3,19 +3,14 @@
import java.io.Serializable;
import java.util.Map;
-import org.iri_research.renkan.repositories.IRenkanRepository;
-import org.iri_research.renkan.repositories.ProjectsRepository;
-
public interface ISyncEventManager<T, ID extends Serializable> {
- public void dispatchEvent(Map<String, Object> data);
+ public void dispatchEvent(String clientId, Map<String, Object> data);
- public void update(Map<String, Object> data);
- public void insert(Map<String, Object> data);
- public void delete(Map<String, Object> data);
- public void nullOperation(Map<String, Object> data);
+ public void update(String clientId, Map<String, Object> data);
+ public void insert(String clientId, Map<String, Object> data);
+ public void delete(String clientId, Map<String, Object> data);
+ public void nullOperation(String clientId, Map<String, Object> data);
- public ProjectsRepository getProjectsRepository();
- public IRenkanRepository<T,ID> getObjectRepository();
}
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java Mon Feb 11 10:34:23 2013 +0100
@@ -43,7 +43,7 @@
@Override
- public void insert(Map<String, Object> data) {
+ public void insert(String clientId, Map<String, Object> data) {
// get project
this.logger.debug("NodeSyncEventManager: insert Node");
@@ -89,7 +89,7 @@
}
@Override
- public void nullOperation(Map<String, Object> data) {
+ public void nullOperation(String clientId, Map<String, Object> data) {
this.logger.debug("nullOperation: NOP");
}
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/ProjectSyncEventManager.java Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/ProjectSyncEventManager.java Mon Feb 11 10:34:23 2013 +0100
@@ -31,7 +31,7 @@
* @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#insert(java.util.Map)
*/
@Override
- public void insert(Map<String, Object> data) {
+ public void insert(String clientId, Map<String, Object> data) {
this.logger.debug("Insert called, do nothing");
// do nothing
}
@@ -40,7 +40,7 @@
* @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#delete(java.util.Map)
*/
@Override
- public void delete(Map<String, Object> data) {
+ public void delete(String clientId, Map<String, Object> data) {
this.logger.debug("Delete called, do nothing");
// do nothing
}
@@ -49,7 +49,7 @@
* @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#nullOperation(java.util.Map)
*/
@Override
- public void nullOperation(Map<String, Object> data) {
+ public void nullOperation(String clientId, Map<String, Object> data) {
this.logger.debug("Null called, do nothing");
// do nothing
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/RosterSyncEventManager.java Mon Feb 11 10:34:23 2013 +0100
@@ -0,0 +1,196 @@
+package org.iri_research.renkan.coweb.event;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Named;
+
+import org.coweb.CowebException;
+import org.iri_research.renkan.models.RenkanSessionModeratorState;
+import org.iri_research.renkan.models.RosterUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+@Named
+public class RosterSyncEventManager implements ISyncEventManager<RosterUser, String> {
+
+ private final Logger logger = LoggerFactory.getLogger(RosterSyncEventManager.class);
+
+
+ @Override
+ public void insert(String clientId, Map<String, Object> data) {
+ logger.debug("RosterUserSyncEventManager.insert " + data.toString());
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+ String projectId = (String) values.get("_project_id");
+
+ List<RosterUser> usersList = null;
+
+ if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
+ usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
+ }
+ if(usersList == null) {
+ usersList = new ArrayList<RosterUser>();
+ RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().put(projectId, usersList);
+ }
+
+ String id = (String)values.get("id");
+
+ RosterUser user = null;
+
+ for (RosterUser rosterUser : usersList) {
+ if(rosterUser.getId().equals(id)) {
+ user = rosterUser;
+ break;
+ }
+ }
+ if(user != null) {
+ this.update(clientId, data);
+ return;
+ }
+
+ String title = (String)values.get("title");
+ String description = (String)values.get("description");
+ String uri = (String)values.get("uri");
+ String color = (String)values.get("color");
+ Long site_id = (Long)values.get("site_id");
+
+ user = new RosterUser(id, title, description, uri, color, projectId, site_id, clientId);
+
+ Integer position = (Integer)data.get("position");
+ if(position == null) {
+ position = new Integer(0);
+ }
+
+ usersList.add(position.intValue(), user);
+
+ logger.debug("RosterUserSyncEventManager.insert in " + projectId + " : " + RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().toString());
+
+ }
+
+ @Override
+ public void nullOperation(String clientId, Map<String, Object> data) {
+ // do nothing
+ return;
+ }
+
+ @Override
+ public void update(String clientId, Map<String, Object> data) {
+ logger.debug("RosterUserSyncEventManager.update " + data.toString());
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+ String projectId = (String) values.get("_project_id");
+
+ List<RosterUser> usersList = null;
+
+ if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
+ usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
+ }
+
+ if(usersList == null) {
+ logger.debug("RosterUserSyncEventManager.update : null user list");
+ return;
+ }
+
+ String id = (String)values.get("id");
+
+ RosterUser user = null;
+
+ for (RosterUser rosterUser : usersList) {
+ if(rosterUser.getId().equals(id)) {
+ user = rosterUser;
+ break;
+ }
+ }
+
+ if(user == null) {
+ logger.debug("RosterUserSyncEventManager.update : user not found in list");
+ return;
+ }
+
+ String title = (String)values.get("title");
+ String description = (String)values.get("description");
+ String uri = (String)values.get("uri");
+ String color = (String)values.get("color");
+
+ if(title != null) {
+ user.setTitle(title);
+ }
+ if(description != null) {
+ user.setDescription(description);
+ }
+ if(uri != null) {
+ user.setUri(uri);
+ }
+ if(color != null) {
+ user.setColor(color);
+ }
+
+ return;
+
+ }
+
+ @Override
+ public void delete(String clientId, Map<String, Object> data) {
+ logger.debug("RosterUserSyncEventManager.delete " + data.toString());
+
+ @SuppressWarnings("unchecked")
+ Map<String, Object> values = (Map<String, Object>) data.get("value");
+ String projectId = (String) values.get("_project_id");
+
+ List<RosterUser> usersList = null;
+
+ if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
+ usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
+ }
+
+ if(usersList == null) {
+ logger.debug("RosterUserSyncEventManager.delete : null user list");
+ return;
+ }
+
+ Integer position = (Integer)data.get("position");
+
+ if(position == null || position < 0) {
+ throw new CowebException("object delete: bad delete position", String.format("Bad position %s not found", position==null?"null":position.toString()));
+ }
+ int index = position.intValue();
+
+ usersList.remove(index);
+
+ if(usersList.isEmpty()) {
+ RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().remove(projectId);
+ }
+
+ return;
+
+ }
+
+ @Override
+ public void dispatchEvent(String clientId, Map<String, Object> data) {
+
+ String eventType = (String) data.get("type");
+
+ if("null".equalsIgnoreCase(eventType)) {
+ this.nullOperation(clientId, data);
+ }
+ else if ("update".equalsIgnoreCase(eventType)) {
+ this.update(clientId, data);
+ }
+ else if ("insert".equalsIgnoreCase(eventType)) {
+ this.insert(clientId, data);
+ }
+ else if("delete".equalsIgnoreCase(eventType)) {
+ this.delete(clientId, data);
+ }
+ else {
+ logger.warn(String.format("dispatchEvent : eventType unknown %s", eventType));
+ }
+ }
+
+
+}
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/UserSyncEventManager.java Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/UserSyncEventManager.java Mon Feb 11 10:34:23 2013 +0100
@@ -35,7 +35,7 @@
@Override
- public void insert(Map<String, Object> data) {
+ public void insert(String clientId, Map<String, Object> data) {
// get project
this.logger.debug("UserSyncEventManager: insert User");
@@ -76,7 +76,7 @@
}
@Override
- public void nullOperation(Map<String, Object> data) {
+ public void nullOperation(String clientId, Map<String, Object> data) {
this.logger.debug("nullOperation: NOP");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/RenkanSessionModeratorState.java Mon Feb 11 10:34:23 2013 +0100
@@ -0,0 +1,27 @@
+package org.iri_research.renkan.models;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public enum RenkanSessionModeratorState {
+ INSTANCE;
+
+ private Map<String, String> usersActivationMap = new HashMap<String, String>();
+ private Map<String, List<String>> projectsActivationMap = new HashMap<String, List<String>>();
+ private Map<String, List<RosterUser>> projectsUsersList = new HashMap<String, List<RosterUser>>();
+
+ public Map<String, String> getUsersActivationMap() {
+ return usersActivationMap;
+ }
+
+ public Map<String, List<String>> getProjectsActivationMap() {
+ return projectsActivationMap;
+ }
+
+ public Map<String, List<RosterUser>> getProjectsUsersList() {
+ return projectsUsersList;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/RosterUser.java Mon Feb 11 10:34:23 2013 +0100
@@ -0,0 +1,53 @@
+package org.iri_research.renkan.models;
+
+public class RosterUser extends AbstractRenkanModel<String> {
+
+ private String color;
+
+ private String project_id;
+ private Long site_id;
+ private String client_id;
+
+ public RosterUser(String id, String title, String description, String uri, String color, String project_id, Long site_id, String client_id) {
+ super(id, title, description, uri);
+
+ this.project_id = project_id;
+ this.site_id = site_id;
+ this.client_id = client_id;
+ this.color = color;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ public String getColor() {
+ return this.color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+ public String getProject_id() {
+ return project_id;
+ }
+
+ public Long getSite_id() {
+ return site_id;
+ }
+
+ public String getClient_id() {
+ return client_id;
+ }
+
+
+}
--- a/server/src/main/resources/log4j.xml Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/resources/log4j.xml Mon Feb 11 10:34:23 2013 +0100
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE log4j:configuration >
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
--- a/server/src/main/webapp/WEB-INF/templates/renkanProjectEdit.html Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/webapp/WEB-INF/templates/renkanProjectEdit.html Mon Feb 11 10:34:23 2013 +0100
@@ -17,18 +17,15 @@
<script src="js/i18n.js" th:src="@{/static/js/i18n.js}"></script>
<script src="js/models.js" th:src="@{/static/js/models.js}"></script>
<script src="js/corenkan-json.js" th:src="@{/static/js/corenkan-json.js}"></script>
- <!--script src="js/random-data.js" th:src="@{/static/js/random-data.js}"></script-->
<script src="js/twitter-bin.js" th:src="@{/static/js/twitter-bin.js}"></script>
<script src="js/wikipedia-bin.js" th:src="@{/static/js/wikipedia-bin.js}"></script>
<script src="js/ldtjson-bin.js" th:src="@{/static/js/ldtjson-bin.js}"></script>
<script src="js/paper-renderer.js" th:src="@{/static/js/paper-renderer.js}"></script>
<script type="text/javascript" src="js/config.js" th:src="@{/static/js/config.js}"></script>
- <script type="text/javascript" src="lib/dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true" th:src="@{/static/lib/dojo/dojo.js}"></script>
+ <script type="text/javascript" src="lib/dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true" th:src="@{/static/lib/dojo/dojo.js}"></script>
<script type="text/javascript" th:inline="javascript">
- var _proj;
- require(["corenkan"], function(corenkan) {
- $(function() {
- _renkan = new Rkns.Renkan({
+ $(function() {
+ var _renkan = new Rkns.Renkan({
url: /*[[@{/rest/projects/}+${project.id}]]*/ "data/simple-persist.php",
static_url : /*[[@{/static/}]]*/ "",
bins: [
@@ -71,17 +68,24 @@
}
],
});
- corenkan.app.onStatusChange = function(status) {
- if(status == "ready") {
- Rkns.jsonIO(_renkan, {
- url: /*[[@{/rest/projects/}+${project.id}]]*/ "data/simple-persist.php",
- callback: function(_proj, _renkan) {
- corenkan.app.setObjects(_renkan);
- }
- });
- }
- };
- });
+ var corenkanConfig = {
+ projectId: /*[[${project.id}]]*/"new_project",
+ renkan : _renkan
+ };
+
+ require({corenkanConfig: corenkanConfig}, ["corenkan"], function(corenkan) {
+ corenkan.app.onStatusChange = function(status) {
+ if(status == "ready") {
+ _renkan.renderer.autoScale();
+ /*Rkns.jsonIO(_renkan, {*/
+ /*url: *//*[[@{/rest/projects/}+${project.id}]]*/ /*"data/simple-persist.php",*/
+ //callback: function(_proj, _renkan) {
+ // corenkan.app.setObjects(_renkan);
+ // }
+ //});
+ }
+ };
+ });
});
</script>
<link rel="stylesheet" href="css/renkan.css" th:href="@{/static/css/renkan.css}"/>
--- a/server/src/main/webapp/static/js/config.js Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/webapp/static/js/config.js Mon Feb 11 10:34:23 2013 +0100
@@ -19,7 +19,7 @@
name: 'dojo',
location:'static/lib/dojo',
main:'main'
- }]
+ }],
/*{
name: 'dijit',
location:'lib/dijit',
@@ -33,10 +33,9 @@
};
var cowebConfig = {
- baseUrl: window.location.protocol + '//' +window.location.host,
- adminUrl : '/renkan/admin',
- debug: false,
- //useWebSockets: true
+ baseUrl: window.location.protocol + '//' +window.location.host,
+ adminUrl : '/renkan/admin',
+ debug: false,
+ //useWebSockets: true
};
-
--- a/server/src/main/webapp/static/js/corenkan-json.js Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/webapp/static/js/corenkan-json.js Mon Feb 11 10:34:23 2013 +0100
@@ -1,6 +1,6 @@
Rkns.jsonIO = function(_renkan, _opts) {
- var _proj = _renkan.project;
+ /*var _proj = _renkan.project;
if (typeof _opts.http_method == "undefined") {
_opts.http_method = 'PUT';
}
@@ -15,5 +15,5 @@
}
});
};
- _load();
+ _load();*/
};
--- a/server/src/main/webapp/static/js/corenkan.js Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/webapp/static/js/corenkan.js Mon Feb 11 10:34:23 2013 +0100
@@ -1,27 +1,33 @@
-//TODO add underscore as requirement
+/**
+ * TODO: add js header
+ */
+
define([
"dojo",
"dojo/cookie",
+ "dojo/json",
"coweb/main",
"rcolor",
- "underscore"
-], function(dojo, cookie, coweb, RColor, underscore) {
+], function(dojo, cookie, json, coweb, RColor) {
var CoRenkan = function() {
};
var proto = CoRenkan.prototype;
-
- var _ = underscore;
-
+
proto.init = function() {
- console.log("ready callback");
+ console.log("ready callback", dojo.config.corenkanConfig);
- //this.initCollab();
- var that = this;
+ this.renkan = dojo.config.corenkanConfig.renkan;
+ this.project = dojo.config.corenkanConfig.renkan.project;
+
+ this.initCollab(dojo.config.corenkanConfig.projectId);
var sess = coweb.initSession();
-
+ this.session = sess;
+
+ var that = this;
+
sess.onStatusChange = function(status) {
console.log(status);
if(typeof that.onStatusChange === "function") {
@@ -29,28 +35,41 @@
}
};
- sess.prepare().then(function(data) {
+ sess.prepare({userDefined: {project_id:dojo.config.corenkanConfig.projectId}, collab: true}).then(function(data) {
console.log("Prepare ok : ", data);
+ that.setObjects();
});
- this.project = null;
};
- proto.initCollab = function(id) {
- this.collab = coweb.initCollab({id : id});
+ proto.initCollab = function(id) {
+
+ this.users_collab = coweb.initCollab({id: "users_" + id});
+
+ this.users_collab.subscribeStateResponse(this, "onUsersStateResponse");
+ this.users_collab.subscribeReady(this, "onLocalJoin");
+ this.users_collab.subscribeSiteJoin(this, 'onRemoteJoin');
+ this.users_collab.subscribeSiteLeave(this, 'onRemoteLeave');
+ this.users_collab.subscribeSync("roster", this, "onRemoteRosterChange");
+
+
+ this.collab = coweb.initCollab({id : "renkan_" + id});
+
+ this.collab.subscribeStateResponse(this, "onStateResponse");
+
this.collab.subscribeSync("project", this, "onRemoteProjectChange");
this.collab.subscribeSync("user", this, "onRemoteUserChange");
this.collab.subscribeSync("node", this, "onRemoteNodeChange");
this.collab.subscribeSync("edge", this, "onRemoteEdgeChange");
- this.collab.subscribeSync("_roster", this, "onRemoteRosterChange");
- this.collab.subscribeReady(this, 'onLocalJoin');
- this.collab.subscribeSiteJoin(this, 'onRemoteJoin');
- this.collab.subscribeSiteLeave(this, 'onRemoteLeave');
};
proto.onLocalJoin = function(params) {
console.log("Local join", params);
+ this.current_site = params.site;
+ if(typeof this.renkan !== "undefined" && this.renkan != null && typeof this.renkan.current_user != "undefined") {
+ this.renkan.current_user.set("site_id", params.site);
+ }
};
@@ -66,9 +85,28 @@
if(typeof this.renkan === "undefined" || this.renkan == null || typeof this.renkan.current_user_list === "undefined" || this.renkan.current_user_list == null) {
return;
}
+ for ( var user in this.renkan.current_user_list.filter(function(u) { return u.get("site_id") == params.site; })) {
+ this.renkan.current_user_list.remove(user);
+ }
};
+ proto.onUsersStateResponse = function(state) {
+ user_list = json.parse(state);
+ console.log("Users State response", user_list);
+ _.each(user_list, function(user, i, l) {
+ user['_id'] = user['id'];
+ });
+ this.renkan.current_user_list.reset(user_list, {silent: true});
+ };
+
+ proto.onStateResponse = function(state) {
+ obj = json.parse(state);
+ console.log("State response", obj);
+ obj['_id'] = obj['id'];
+ this.project.set(obj, {silent: true});
+ };
+
function prepareValues(obj,c) {
values = {};
for(var fieldname in c.changes) {
@@ -79,8 +117,12 @@
return values;
}
- proto.addObjectBind = function(type, obj, c, options) {
- console.log("add " + type,obj, c, options, this.project.toJSON());
+ proto.addObjectBind = function(type, obj, c, options, collab) {
+ console.log("add " + type,obj, c, options);
+ if(this.project == null) {
+ console.log("null project exiting");
+ return;
+ }
var values = obj.toJSON();
var new_values = {
id: obj.id,
@@ -93,10 +135,10 @@
values[k] = new_values[k];
}
console.log("add values : ", values);
- this.collab.sendSync(type, values, "insert", options.index);
+ collab.sendSync(type, values, "insert", options.index);
};
- proto.removeObjectBind = function(type, obj, c, options) {
+ proto.removeObjectBind = function(type, obj, c, options, collab) {
console.log("delete " + type,obj, c, options);
var values = {
id: obj.id,
@@ -105,10 +147,10 @@
_project_id : obj.get("project").id,
_user_id : (this.project.current_user!=null)?this.project.current_user.id:null
};
- this.collab.sendSync(type, values, "delete", options.index);
+ collab.sendSync(type, values, "delete", options.index);
};
- proto.updateObjectBind = function(type, obj, options) {
+ proto.updateObjectBind = function(type, obj, options, collab) {
console.log("change " + type,obj, options);
if(typeof obj != "undefined" && obj.hasChanged()) {
var values = {
@@ -118,7 +160,7 @@
_user_id : (this.project.current_user!=null)?this.project.current_user.id:null
};
_.extend(values,obj.changed);
- this.collab.sendSync(type, values);
+ collab.sendSync(type, values);
}
};
@@ -144,15 +186,14 @@
};
- proto.setObjects = function(renkan) {
+ proto.setObjects = function() {
console.log(cookie("BAYEUX_BROWSER"));
+ var renkan = this.renkan;
var project = renkan.project;
this.setProject(project);
this.setRenkan(renkan);
-
- this.initCollab("renkan_" + project.id);
-
+
this.setUser(renkan);
};
@@ -164,13 +205,13 @@
var that = this;
renkan.current_user_list.bind("add", function(obj, c, options) {
- that.addObjectBind("_roster", obj, c, options);
+ that.addObjectBind("roster", obj, c, options, that.users_collab);
});
- renkan.current_user_list.bind("remove", function(obj, c, options) {
- that.removeObjectBind("_roster", obj, c, options);
- });
+ //renkan.current_user_list.bind("remove", function(obj, c, options) {
+ // that.removeObjectBind("_roster", obj, c, options, that.users_collab);
+ //});
renkan.current_user_list.bind("change", function(obj, options) {
- that.updateObjectBind("_roster", obj, options);
+ that.updateObjectBind("roster", obj, options, that.users_collab);
});
renkan.current_user_list.bind("change", function(obj, options) {
@@ -193,9 +234,7 @@
}
}
});
-
- this.renkan = renkan;
-
+
};
proto.setUser = function(renkan) {
@@ -216,7 +255,8 @@
id: user_id,
title: "anonymous",
project: project,
- color: color.get(true, 0.3, 0.99)
+ color: color.get(true, 0.3, 0.99),
+ site_id: this.current_site
};
}
else {
@@ -268,43 +308,41 @@
project.get("nodes").bind("add", function(obj, c, options) {
- that.addObjectBind("node", obj, c, options);
+ that.addObjectBind("node", obj, c, options, that.collab);
});
project.get("nodes").bind("remove", function(obj, c, options) {
- that.removeObjectBind("node", obj, c, options);
+ that.removeObjectBind("node", obj, c, options, that.collab);
});
project.get("nodes").bind("change", function(obj, options) {
- that.updateObjectBind("node", obj, options);
+ that.updateObjectBind("node", obj, options, that.collab);
});
project.get("users").bind("add", function(obj, c, options) {
- that.addObjectBind("user", obj, c, options);
+ that.addObjectBind("user", obj, c, options, that.collab);
});
project.get("users").bind("remove", function(obj, c, options) {
- that.removeObjectBind("user", obj, c, options);
+ that.removeObjectBind("user", obj, c, options, that.collab);
});
project.get("users").bind("change", function(obj, options) {
- that.updateObjectBind("user", obj, options);
+ that.updateObjectBind("user", obj, options, that.collab);
});
project.get("edges").bind("add", function(obj, c, options) {
- that.addObjectBind("edge", obj, c, options);
+ that.addObjectBind("edge", obj, c, options, that.collab);
});
project.get("edges").bind("remove", function(obj, c, options) {
- that.removeObjectBind("edge", obj, c, options);
+ that.removeObjectBind("edge", obj, c, options, that.collab);
});
project.get("edges").bind("change", function(obj, options) {
- that.updateObjectBind("edge", obj, options);
+ that.updateObjectBind("edge", obj, options, that.collab);
});
-
- this.project = project;
};
--- a/server/src/main/webapp/static/js/ldtjson-bin.js Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/webapp/static/js/ldtjson-bin.js Mon Feb 11 10:34:23 2013 +0100
@@ -13,6 +13,7 @@
);
Rkns.Ldt.ProjectBin.prototype._init = function(_renkan, _opts) {
+ this.renkan = _renkan;
this.proj_id = _opts.project_id;
this.ldt_platform = _opts.ldt_platform || "http://ldt.iri.centrepompidou.fr/";
this.title_$.html(_opts.title);
@@ -108,7 +109,7 @@
} else {
this.$.show();
}
- _renkan.resizeBins();
+ this.renkan.resizeBins();
}
Rkns.Ldt.ProjectBin.prototype.refresh = function() {
--- a/server/src/main/webapp/static/js/models.js Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/webapp/static/js/models.js Mon Feb 11 10:34:23 2013 +0100
@@ -253,7 +253,8 @@
uri: this.get("uri"),
description: this.get("description"),
color: this.get("color"),
- project: (this.get("project") != null)?this.get("project").get("id"):null
+ project: (this.get("project") != null)?this.get("project").get("id"):null,
+ site_id: this.get("site_id")
};
},
});
--- a/server/src/main/webapp/static/js/twitter-bin.js Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/webapp/static/js/twitter-bin.js Mon Feb 11 10:34:23 2013 +0100
@@ -38,6 +38,7 @@
);
Rkns.Twitter.Bin.prototype._init = function(_renkan, _opts) {
+ this.renkan = _renkan;
this.search = _opts.search;
this.title_icon_$.addClass('Rk-Twitter-Title-Icon');
this.title_$.html(this.search).addClass("Rk-Twitter-Title");
@@ -133,7 +134,7 @@
} else {
this.$.show();
}
- _renkan.resizeBins();
+ this.renkan.resizeBins();
}
Rkns.Twitter.Bin.prototype.refresh = function() {
--- a/server/src/main/webapp/static/js/wikipedia-bin.js Mon Jan 14 16:00:07 2013 +0100
+++ b/server/src/main/webapp/static/js/wikipedia-bin.js Mon Feb 11 10:34:23 2013 +0100
@@ -33,6 +33,7 @@
);
Rkns.Wikipedia.Bin.prototype._init = function(_renkan, _opts) {
+ this.renkan = _renkan;
this.search = _opts.search;
this.lang = _opts.lang || "en";
this.title_icon_$.addClass('Rk-Wikipedia-Title-Icon Rk-Wikipedia-Lang-' + this.lang);
@@ -79,7 +80,7 @@
} else {
this.$.show();
}
- _renkan.resizeBins();
+ this.renkan.resizeBins();
}
Rkns.Wikipedia.Bin.prototype.refresh = function() {