First version of space level.
authorymh <ymh.work@gmail.com>
Sat, 09 Mar 2013 02:19:49 +0100
changeset 71 9af0874ce43f
parent 70 47b3125130a2
child 72 dbd90c784424
First version of space level.
.classpath
server/pom.xml
server/src/main/java/org/iri_research/renkan/controller/RenkanRootController.java
server/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java
server/src/main/java/org/iri_research/renkan/models/Edge.java
server/src/main/java/org/iri_research/renkan/models/Node.java
server/src/main/java/org/iri_research/renkan/models/Project.java
server/src/main/java/org/iri_research/renkan/models/Space.java
server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepository.java
server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryImpl.java
server/src/main/java/org/iri_research/renkan/repositories/SpacesRepository.java
server/src/main/java/org/iri_research/renkan/rest/ObjectMapperProvider.java
server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java
server/src/main/java/org/iri_research/renkan/rest/RenkanResource.java
server/src/main/java/org/iri_research/renkan/rest/SpacesResource.java
server/src/main/resources/log4j.xml
server/src/main/webapp/WEB-INF/i18n/messages_en.properties
server/src/main/webapp/WEB-INF/i18n/messages_fr.properties
server/src/main/webapp/WEB-INF/templates/projectIndex.html
server/src/main/webapp/WEB-INF/templates/renkanIndex.html
server/src/main/webapp/WEB-INF/web.xml
server/src/test/java/org/iri_research/renkan/test/repositories/ProjectSyncsRepositoryTest.java
server/src/test/java/org/iri_research/renkan/test/repositories/ProjectsRepositoryTest.java
server/src/test/java/org/iri_research/renkan/test/repositories/SpacesRepositoryTest.java
server/src/test/java/org/iri_research/renkan/test/rest/SpaceRestTest.java
server/src/test/resources/org/iri_research/renkan/test/repositories/mongo-config.xml
server/src/test/resources/org/iri_research/renkan/test/rest/mongo-config.xml
server/src/test/resources/org/iri_research/renkan/test/rest/rest-context.xml
--- a/.classpath	Fri Mar 01 19:14:30 2013 +0100
+++ b/.classpath	Sat Mar 09 02:19:49 2013 +0100
@@ -46,9 +46,19 @@
 			<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="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.1.4/jackson-core-2.1.4.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.1.4/jackson-databind-2.1.4.jar"/>
 	<classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-websocket-jetty/2.5.1/cometd-websocket-jetty-2.5.1.jar"/>
 	<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-websocket/8.1.9.v20130131/jetty-websocket-8.1.9.v20130131.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-annotations/2.1.4/jackson-annotations-2.1.4.jar">
+		<attributes>
+			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-test-framework/jersey-test-framework-core/1.17/jersey-test-framework-core-1.17.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-servlet/1.17/jersey-servlet-1.17.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/contribs/jersey-spring/1.17/jersey-spring-1.17.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-client/1.17/jersey-client-1.17.jar"/>
+	<classpathentry kind="var" path="M2_REPO/joda-time/joda-time/2.1/joda-time-2.1.jar"/>
 	<classpathentry kind="output" path="server/target/classes"/>
 </classpath>
--- a/server/pom.xml	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/pom.xml	Sat Mar 09 02:19:49 2013 +0100
@@ -12,11 +12,14 @@
         <cowebx-version>1.0</cowebx-version>
         <jersey-version>1.17</jersey-version>
         <spring-version>3.2.1.RELEASE</spring-version>
+        <spring-security-version>3.1.3.RELEASE</spring-security-version>
         <!--jetty-version>9.0.0.RC0</jetty-version-->
         <jetty-version>8.1.9.v20130131</jetty-version>
         <junit-version>4.10</junit-version>
         <thymeleaf-version>2.0.15</thymeleaf-version>
         <cometd-version>2.5.1</cometd-version>
+        <jackson-version>2.1.4</jackson-version>
+        <joda-version>2.1</joda-version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
 
@@ -99,7 +102,7 @@
             </plugin>
         </plugins>
     </build>
-    <repositories>    
+    <repositories>
         <repository>
             <id>spring-maven-release</id>
             <name>Spring Maven Release Repository</name>
@@ -196,6 +199,12 @@
                 </exclusion>
             </exclusions>
         </dependency>
+		<dependency>
+		    <groupId>com.sun.jersey.jersey-test-framework</groupId>
+		    <artifactId>jersey-test-framework-grizzly2</artifactId>
+		    <version>${jersey-version}</version>
+		    <scope>test</scope>
+		</dependency>
         <dependency>
             <groupId>org.mongodb</groupId>
             <artifactId>mongo-java-driver</artifactId>
@@ -204,7 +213,7 @@
         <dependency> 
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-log4j12</artifactId>
-            <version>1.6.6</version>
+            <version>1.7.2</version>
         </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
@@ -296,7 +305,7 @@
         <dependency>
             <groupId>com.fasterxml.jackson.jaxrs</groupId>
             <artifactId>jackson-jaxrs-json-provider</artifactId>
-            <version>2.1.2</version>
+            <version>${jackson-version}</version>
         </dependency>
         <dependency>
             <groupId>commons-codec</groupId>
@@ -327,6 +336,31 @@
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-util</artifactId>
             <version>${jetty-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-core</artifactId>
+            <version>${spring-security-version}</version>
+        </dependency> 
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-web</artifactId>
+            <version>${spring-security-version}</version>
+        </dependency> 
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-config</artifactId>
+            <version>${spring-security-version}</version>
+        </dependency>
+        <dependency>
+	       <groupId>de.undercouch</groupId>
+	       <artifactId>bson4jackson</artifactId>
+	       <version>2.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>${joda-version}</version>
         </dependency>        
     </dependencies>
     <organization>
--- a/server/src/main/java/org/iri_research/renkan/controller/RenkanRootController.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/controller/RenkanRootController.java	Sat Mar 09 02:19:49 2013 +0100
@@ -1,16 +1,22 @@
 package org.iri_research.renkan.controller;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.Space;
 import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.iri_research.renkan.repositories.SpacesRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.servlet.ModelAndView;
 
 
@@ -18,22 +24,50 @@
 @RequestMapping("/")
 public class RenkanRootController {
 
-	@SuppressWarnings("unused")
 	private final Logger logger = LoggerFactory.getLogger(RenkanRootController.class);
 		
 	@Autowired
-	private ProjectsRepository projectRepository;
+	private ProjectsRepository projectsRepository;
+	
+	@Autowired
+	private SpacesRepository spacesRepository;
 		
 	@RequestMapping(value="", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
 	public ModelAndView renkanIndex() {
 				
 		Map<String, Object> model = new HashMap<String, Object>();
 		
-		Iterable<Project> projects = this.projectRepository.findAll();
+		Iterable<Space> spaces = this.spacesRepository.findAll();
+		
+		model.put("spaces", spaces);
+		
+		return new ModelAndView("renkanIndex", model);
+	}
+
+	@RequestMapping(value="/s/{space_id}", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
+	public ModelAndView spaceIndex(@PathVariable("space_id") String spaceId) {
+		
+		logger.debug("SpaceId : " + (spaceId== null ? "null" : spaceId));
+		
+		Map<String, Object> model = new HashMap<String, Object>();
+
+		if("_".equals(spaceId)) {
+			spaceId = null;
+		}
+		
+		Space space = this.spacesRepository.findOne(spaceId);
+		
+		if(null == space) {
+			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Space " + spaceId + " not found.");
+		}
+		
+		model.put("space", space);
+		
+		List<Project> projects = this.projectsRepository.findBySpaceId(spaceId);
 		
 		model.put("projects", projects);
 		
-		return new ModelAndView("renkanIndex", model);
+		return new ModelAndView("projectIndex", model);
 	}
 	
 		
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java	Sat Mar 09 02:19:49 2013 +0100
@@ -69,7 +69,7 @@
 		
 		String node_id = (String)values.get("id");
 		
-		Node node = new Node(node_id, (String)values.get("title"), (String)values.get("description"), (String)values.get("uri"), (String)values.get("color"), project_id, creator_id, nodePosition, image);
+		Node node = new Node(node_id, (String)values.get("title"), (String)values.get("description"), (String)values.get("uri"), (String)values.get("color"), creator_id, nodePosition, image, project_id);
 		
 		Integer position = (Integer)data.get("position");
 		
--- a/server/src/main/java/org/iri_research/renkan/models/Edge.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/models/Edge.java	Sat Mar 09 02:19:49 2013 +0100
@@ -2,6 +2,9 @@
 
 import org.springframework.data.mongodb.core.mapping.DBRef;
 import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
 
 
 @Document(collection="edges")
@@ -13,27 +16,32 @@
 	@DBRef
 	private Node to;
 	
-	private String project_id;
+	@Field("project_id")
+	@JsonProperty("project_id")
+	private String projectId;
 	
-	private String created_by;
+	@Field("created_by")
+	@JsonProperty("created_by")
+	private String createdBy;
 	
 
-	public Edge(String id, String title, String description, String uri, String color, Node from, Node to, String created_by, String project_id) {
+	public Edge(String id, String title, String description, String uri, String color, Node from, Node to, String createdBy, String projectId) {
 		super(id,title, description, uri, color);
 		this.from = from;
 		this.to = to;
-		this.created_by = created_by;
-		this.project_id = project_id;
+		this.createdBy = createdBy;
+		this.projectId = projectId;
 	}
 
 
-	public String getProject_id() {
-		return project_id;
+	@JsonProperty("project_id")
+	public String getProjectId() {
+		return projectId;
 	}
 
 
-	public String getCreated_by() {
-		return created_by;
+	public String getCreatedBy() {
+		return createdBy;
 	}
 	
 	public String getFrom() {
--- a/server/src/main/java/org/iri_research/renkan/models/Node.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/models/Node.java	Sat Mar 09 02:19:49 2013 +0100
@@ -2,23 +2,30 @@
 
 import org.springframework.data.mongodb.core.geo.Point;
 import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
 
 @Document(collection="nodes")
 public class Node extends AbstractRenkanModel<String> {
 
 
-	public Node(String id, String title, String description, String uri, String color, String project_id, String created_by, Point position, String image) {
+	public Node(String id, String title, String description, String uri, String color, String createdBy, Point position, String image, String projectId) {
 		super(id, title, description, uri, color);
 		
-		this.project_id = project_id;
-		this.created_by = created_by;
+		this.projectId = projectId;
+		this.createdBy = createdBy;
 		this.position = position;
 		this.image = image;
 	}	
-	
-	private String project_id = null;	
 
-	private String created_by = null;
+	@Field("project_id")
+	@JsonProperty("project_id")	
+	private String projectId = null;	
+
+	@Field("created_by")
+	@JsonProperty("created_by")
+	private String createdBy = null;
 	
 	private Point position = null;
 
@@ -32,12 +39,14 @@
 		return image;
 	}
 
-	public String getProject_id() {
-		return project_id;
+	@JsonProperty("project_id")
+	public String getProjectId() {
+		return projectId;
 	}
 
-	public String getCreated_by() {
-		return created_by;
+	@JsonProperty("created_by")
+	public String getCreatedBy() {
+		return createdBy;
 	}
 
 }
--- a/server/src/main/java/org/iri_research/renkan/models/Project.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/models/Project.java	Sat Mar 09 02:19:49 2013 +0100
@@ -15,6 +15,9 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.data.mongodb.core.mapping.DBRef;
 import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
 
 @Document(collection="projects")
 public class Project extends AbstractRenkanModel<String> {
@@ -22,10 +25,16 @@
 	@SuppressWarnings("unused")
 	private static Logger logger = LoggerFactory.getLogger(Project.class); 
 			
+	@Field("rev_counter")
 	private int revCounter = 1;
 	
-	private Date created;
-		
+	private Date created;	
+	
+	// Space
+	@Field("space_id")
+	@JsonProperty("space_id")
+	private String spaceId = null;
+	
 	// Nodes
 	@DBRef
 	private List<Node> nodes = new ArrayList<Node>();
@@ -39,18 +48,19 @@
 	private List<User> users = new ArrayList<User>();
 	
 	
-	public Project(String id, String title, String description, String uri, Date created,
+	public Project(String spaceId, String id, String title, String description, String uri, Date created,
 			int revCounter) {
 		super(id,title, description, uri, null);
 		this.revCounter = revCounter;
+		this.spaceId = spaceId;
 		this.created = created;
 		if(this.created == null) {
 			this.created = new Date();
 		}
 	}
 
-	public Project(String id, String title, String description, String uri, Date created) {
-		this(id,title, description, uri, created, 1);
+	public Project(String spaceId, String id, String title, String description, String uri, Date created) {
+		this(spaceId, id,title, description, uri, created, 1);
 	}
 	
 	@SuppressWarnings("unused")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/Space.java	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,68 @@
+package org.iri_research.renkan.models;
+
+import java.util.Date;
+
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@Document(collection="spaces")
+public class Space extends AbstractRenkanModel<String> {
+	
+
+	public Space(String id, String title, String description, String binConfig, String uri, String color, String createdBy, String image, Date created) {
+		super(id, title, description, uri, color);
+		
+		this.binConfig = binConfig;
+		this.createdBy = createdBy;
+		this.image = image;
+		this.created = created;
+		if(this.created == null) {
+			this.created = new Date();
+		}
+	}
+	
+	@SuppressWarnings("unused")
+	private Space() {		
+	}
+
+	@Field("bin_config")
+	@JsonProperty("bin_config")
+	private String binConfig;
+	
+	@Field("created_by")
+	@JsonProperty("created_by")
+	private String createdBy = null;	
+	private String image;
+	private Date created;
+	
+	public String getImage() {
+		return image;
+	}
+
+	@JsonProperty("created_by")
+	public String getCreatedBy() {
+		return createdBy;
+	}
+	
+	public Date getCreated() {
+		return created;
+	}
+	
+	public void setCreated(Date date) {
+		this.created = date;
+		
+	}
+
+	@JsonProperty("bin_config")
+	public String getBinConfig() {
+		return binConfig;
+	}
+
+	@JsonProperty("bin_config")
+	public void setBinConfig(String bin_config) {
+		this.binConfig = bin_config;
+	}
+	
+}
\ No newline at end of file
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepository.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepository.java	Sat Mar 09 02:19:49 2013 +0100
@@ -1,7 +1,11 @@
 package org.iri_research.renkan.repositories;
 
+import java.util.List;
+
 import org.iri_research.renkan.models.Project;
 
 public interface ProjectsRepository extends IRenkanRepository<Project, String>, ProjectsRepositoryCustom {
+	
+	List<Project> findBySpaceId(String spaceId);
 
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryImpl.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryImpl.java	Sat Mar 09 02:19:49 2013 +0100
@@ -16,7 +16,7 @@
 	
 	@Override
 	public int getRevCounter(String projectId)  {		
-		Project p = this.mongoTemplate.findAndModify(query(where("id").is(projectId)), new Update().inc("revCounter", 1), Project.class);
+		Project p = this.mongoTemplate.findAndModify(query(where("id").is(projectId)), new Update().inc("rev_counter", 1), Project.class);
 		
 		if(p == null) {
 			return -1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/SpacesRepository.java	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,7 @@
+package org.iri_research.renkan.repositories;
+
+import org.iri_research.renkan.models.Space;
+
+public interface SpacesRepository extends IRenkanRepository<Space, String> {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/rest/ObjectMapperProvider.java	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,23 @@
+package org.iri_research.renkan.rest;
+
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+@Component
+@Provider
+public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
+
+	@Override
+	public ObjectMapper getContext(Class<?> type) {
+		ObjectMapper objectMapper = new ObjectMapper();
+		objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+		
+		return objectMapper;
+	}
+
+}
--- a/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java	Sat Mar 09 02:19:49 2013 +0100
@@ -1,168 +1,55 @@
 package org.iri_research.renkan.rest;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
 
 import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.repositories.IRenkanRepository;
 import org.iri_research.renkan.repositories.ProjectsRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import com.mongodb.BasicDBObject;
-import com.mongodb.DBCollection;
-import com.mongodb.DBCursor;
-import com.mongodb.DBObject;
-import com.mongodb.util.JSON;
 import com.sun.jersey.spi.resource.Singleton;
 
 
 @Singleton
 @Path("projects")
 @Component
-public class ProjectsResource {
+public class ProjectsResource extends RenkanResource<Project, String> {
 	
+	@SuppressWarnings("unused")
 	private Logger logger = LoggerFactory.getLogger(ProjectsResource.class);
 	
 	@Autowired
-	private ProjectsRepository projectRepository;
-	
-	@Context
-	private UriInfo uriInfo;
-		
-	private DBCollection getCollection() {		
-		return projectRepository.getCollection();
+	private ProjectsRepository projectsRepository;
+
+	@Override
+	protected IRenkanRepository<Project, String> getRepository() {
+		return this.projectsRepository;
 	}
 
-	@GET
-	@Path("{id : [a-zA-Z\\-0-9]+}")
-	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
-	public Project getProject(@PathParam("id") String projectId) {
-		
-		this.logger.debug("GetProject: " + projectId);
-				
-		Project project = this.projectRepository.findOne(projectId);
-		
-		if (null == project) {
-			throw new WebApplicationException(Status.NOT_FOUND);
-		}
-		
-		return project;				
-	}
-	
-	@DELETE
-	@Path("{id : [a-zA-Z\\-0-9]+}")
-	@Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
-	public Response deleteProject(@PathParam("id") String projectId) {
-		
-		this.logger.debug("DeleteProject : id " + projectId);
-		
-		this.projectRepository.delete(projectId);
-		return Response.ok(this.uriInfo.getAbsolutePathBuilder().segment(projectId).build().toString() + " deleted").build();
-		
-	}
-
-
-	/**
-	 * test: curl -i -X PUT -H 'Content-Type: application/json' -d @test-data.json  http://localhost:8080/renkan/rest/projects/12eff140-e65c-11e1-aff1-0800200c9a66
-	 * @param projectId
-	 * @param projectContent
-	 */
-	@PUT
-	@Path("{id : [a-zA-Z\\-0-9]+}")
-	@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
-	public Response putProject(@PathParam("id") String projectId, Project project) {
-
-		if(!projectId.equals(project.getId())) {
-			throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("Id parameter and id in JSON do not match").build());
-		}
-		if(project.getCreated() == null) {
-			project.setCreated(new Date());
-		}
-		this.projectRepository.save(project);
-		return Response.noContent().build();
-		
+	@Override
+	protected String getNewId() {
+		return UUID.randomUUID().toString();
 	}
 
-	
-	@POST
-	@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
-	public Response postProject(Project project) {
-		if(project.getId() != null) {
-			throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("Id in JSON must be null").build());
+	@Override
+	protected void prepareObject(Project obj) {
+		if(obj.getCreated() == null) {
+			obj.setCreated(new Date());
 		}
-		
-		project.setId(UUID.randomUUID().toString());
-		if(project.getCreated() == null) {
-			project.setCreated(new Date());
-		}
-		project = this.projectRepository.save(project);
-		return Response.created(this.uriInfo.getAbsolutePathBuilder().segment(project.getId()).build()).entity(project).build();		
 	}
-		
-	@GET
-	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
-	public String getProjectList() {
-		
-		DBCollection projectCollection = this.getCollection();
-		BasicDBObject keys = new BasicDBObject();
-		keys.put("description", 1);
-		keys.put("title", 1);
-		keys.put("uri", 1);
-		keys.put("created", 1);
-		DBCursor cursor = projectCollection.find(new BasicDBObject(), keys);
-		
-		List<DBObject> res = new ArrayList<DBObject>();
-				
-		try {
-			while(cursor.hasNext()) {
-				DBObject obj = cursor.next();
-				DBObject links = new BasicDBObject();
-				
-				DBObject linkdef = new BasicDBObject();
-				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
-				linkdef.put("method", "get");
-				linkdef.put("produces", MediaType.APPLICATION_JSON + ";charset=utf-8");				
-				links.put("view", linkdef);
-				
-				linkdef = new BasicDBObject();
-				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
-				linkdef.put("method", "put");
-				linkdef.put("consumes", MediaType.APPLICATION_JSON + ";charset=utf-8");				
-				links.put("update", linkdef);
 
-				linkdef = new BasicDBObject();
-				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
-				linkdef.put("method", "delete");
-				links.put("delete", linkdef);				
-				
-				obj.put("__links",  links);
-				res.add(obj);
-			}
-		}
-		finally {
-			cursor.close();
-		}
-		
-		return JSON.serialize(res);
+	@Override
+	protected List<String> getObjectListFieldList() {
+		return Arrays.asList(this.baseObjectListFieldList);
 	}
+	
 		
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/rest/RenkanResource.java	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,172 @@
+package org.iri_research.renkan.rest;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
+
+import org.iri_research.renkan.models.IRenkanModel;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.DBObject;
+
+public abstract class RenkanResource<T extends IRenkanModel<ID>, ID extends Serializable> {
+	
+	private Logger logger = LoggerFactory.getLogger(RenkanResource.class);
+	
+	protected String[] baseObjectListFieldList = {"description","title","uri","created", "color"};
+
+	abstract protected IRenkanRepository<T, ID> getRepository();
+	abstract protected ID getNewId();
+	abstract protected List<String> getObjectListFieldList();
+
+	@Context
+	private UriInfo uriInfo;
+
+	protected DBCollection getCollection() {
+		return this.getRepository().getCollection();
+	}
+	
+	abstract protected void prepareObject(T obj);
+	
+	@GET
+	@Path("{id : [a-zA-Z\\-0-9]+}")
+	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+	public T getObject(@PathParam("id") ID objectId) {
+		
+		this.logger.debug("GetObject: " + objectId);
+				
+		T obj = this.getRepository().findOne(objectId);
+		
+		if (null == obj) {
+			throw new WebApplicationException(Status.NOT_FOUND);
+		}
+		
+		return obj;				
+	}
+	
+	@DELETE
+	@Path("{id : [a-zA-Z\\-0-9]+}")
+	@Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
+	public Response deleteObject(@PathParam("id") ID objectId) {
+		
+		this.logger.debug("DeleteObject : id " + objectId);
+				
+		this.getRepository().delete(objectId);
+		return Response.ok(this.uriInfo.getAbsolutePathBuilder().build().toString() + " deleted").build();
+		
+	}
+	
+	/**
+	 * test: curl -i -X PUT -H 'Content-Type: application/json' -d @test-data.json  http://localhost:8080/renkan/rest/spaces/12eff140-e65c-11e1-aff1-0800200c9a66
+	 * @param objId
+	 * @param objectContent
+	 */
+	@PUT
+	@Path("{id : [a-zA-Z\\-0-9]+}")
+	@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
+	public Response putRenkanObject(@PathParam("id") ID objId, T obj) {
+
+		if(!objId.equals(obj.getId())) {
+			throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("Id parameter and id in JSON do not match").build());
+		}
+		
+		if(!this.getRepository().exists(objId)) {
+			throw new WebApplicationException(Response.status(Status.NOT_FOUND).build());
+		}		
+		
+		this.prepareObject(obj);
+		this.getRepository().save(obj);
+		return Response.noContent().build();
+		
+	}
+	
+	@POST
+	@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
+	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+	public Response postRenkanObject(T obj) {
+
+		if(obj.getId() != null) {
+			throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("Id in JSON must be null").build());
+		}
+				
+		obj.setId(getNewId());
+		this.prepareObject(obj);
+		obj = this.getRepository().save(obj);
+		return Response.created(this.uriInfo.getAbsolutePathBuilder().segment(obj.getId().toString()).build()).entity(obj).build();		
+	}
+		
+
+	@GET
+	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+	public String getObjectList() throws JsonProcessingException {
+		
+		BasicDBObject keys = new BasicDBObject();
+		
+		for (String fieldname : this.getObjectListFieldList()) {
+			keys.put(fieldname, 1);
+		}
+		DBCursor cursor = this.getCollection().find(new BasicDBObject(), keys);
+		
+		List<DBObject> res = new ArrayList<DBObject>();
+				
+		try {
+			while(cursor.hasNext()) {
+				DBObject obj = cursor.next();
+				obj.put("id", obj.get("_id"));
+				DBObject links = new BasicDBObject();
+				
+				DBObject linkdef = new BasicDBObject();
+				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
+				linkdef.put("method", "get");
+				linkdef.put("produces", MediaType.APPLICATION_JSON + ";charset=utf-8");				
+				links.put("view", linkdef);
+				
+				linkdef = new BasicDBObject();
+				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
+				linkdef.put("method", "put");
+				linkdef.put("consumes", MediaType.APPLICATION_JSON + ";charset=utf-8");				
+				links.put("update", linkdef);
+
+				linkdef = new BasicDBObject();
+				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
+				linkdef.put("method", "delete");
+				links.put("delete", linkdef);				
+				
+				obj.put("__links",  links);
+				res.add(obj);
+			}
+		}
+		finally {
+			cursor.close();
+		}
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+		return mapper.writeValueAsString(res);
+	}
+
+
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/rest/SpacesResource.java	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,64 @@
+package org.iri_research.renkan.rest;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import javax.ws.rs.Path;
+
+import org.iri_research.renkan.models.Space;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.iri_research.renkan.repositories.SpacesRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.sun.jersey.spi.resource.Singleton;
+
+@Singleton
+@Path("spaces")
+@Component
+public class SpacesResource extends RenkanResource<Space, String> {
+	
+	@SuppressWarnings("unused")
+	private Logger logger = LoggerFactory.getLogger(SpacesResource.class);
+	
+	private String[] spaceObjectListFieldList = {"created_by","bin_config","image"};
+	
+	@Autowired
+	private SpacesRepository spacesRepository;
+		
+	@Override
+	protected IRenkanRepository<Space, String> getRepository() {		
+		return spacesRepository;
+	}
+
+
+	@Override
+	protected String getNewId() {
+		return UUID.randomUUID().toString();
+	}
+
+
+	@Override
+	protected void prepareObject(Space obj) {
+		if(obj.getCreated() == null) {
+			obj.setCreated(new Date());
+		}
+	}
+
+
+	@Override
+	protected List<String> getObjectListFieldList() {
+		ArrayList<String> fieldList = new ArrayList<>(this.baseObjectListFieldList.length + this.spaceObjectListFieldList.length);
+		fieldList.addAll(Arrays.asList(this.baseObjectListFieldList));
+		fieldList.addAll(Arrays.asList(this.spaceObjectListFieldList));
+		return fieldList;
+	}
+
+
+}
--- a/server/src/main/resources/log4j.xml	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/resources/log4j.xml	Sat Mar 09 02:19:49 2013 +0100
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!DOCTYPE log4j:configuration >
 
 <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
   <appender name="console" class="org.apache.log4j.ConsoleAppender"> 
--- a/server/src/main/webapp/WEB-INF/i18n/messages_en.properties	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/webapp/WEB-INF/i18n/messages_en.properties	Sat Mar 09 02:19:49 2013 +0100
@@ -2,11 +2,20 @@
 date.format = yyyy/MM/dd HH:mm
 
 renkanIndex.new_renkan = New Renkan
+renkanIndex.new_space = New Space
 renkanIndex.renkan_title = or create/open a Renkan with the title
 renkanIndex.project_list = Project list
 renkanIndex.project_name = Name
 renkanIndex.project_creation = Creation
 renkanIndex.project_edit = Edit
-renkanIndex.project_edit_link = Edit projet
+renkanIndex.project_edit_link = Edit project
+
+renkanIndex.space_list = Spaces list
+renkanIndex.space_name = Name
+renkanIndex.space_title = Title
+renkanIndex.space_creation = Creation
+renkanIndex.space_open = Open
+renkanIndex.space_open_link = Open space
+
 
 renkanIndex.js.empty_name_error = Please enter a title
\ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/i18n/messages_fr.properties	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/webapp/WEB-INF/i18n/messages_fr.properties	Sat Mar 09 02:19:49 2013 +0100
@@ -2,12 +2,22 @@
 date.format = dd/MM/yyyy HH:mm
 
 renkanIndex.new_renkan = Nouveau&nbsp;Renkan
+renkanIndex.new_space = Nouvel Espace
 renkanIndex.renkan_titre = ou bien créer un Renkan avec le titre
+
 renkanIndex.project_list = Liste des projets
 renkanIndex.project_title = Titre
 renkanIndex.project_creation = Creation
 renkanIndex.project_edit = Edition
 renkanIndex.project_edit_link = Editer proj.
 
+renkanIndex.space_list = Liste des espace
+renkanIndex.space_name = Nom
+renkanIndex.space_title = Titre
+renkanIndex.space_creation = Creation
+renkanIndex.space_open = Ouvrir
+renkanIndex.space_open_link = Ouvrir esp.
+
+
 renkanIndex.js.empty_name_error = Veuillez entrer un titre
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/projectIndex.html	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,188 @@
+<!doctype html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+        <title>Renkan</title>
+
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+        <meta charset="utf-8"/>
+        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
+
+        <link rel="shortcut icon" href="favicon.ico"/>
+        <script src="lib/jquery.min.js" th:src="@{/static/lib/jquery.min.js}" ></script>
+        <script src="lib/underscore-min.js" th:src="@{/static/lib/underscore-min.js}" ></script>
+        <script src="js/main.js" th:src="@{/static/js/main.js}" ></script>
+
+        <style>
+        /*<![CDATA[*/
+            body {
+              margin: 0;
+              height: 100%;
+              color: #333;
+              font: 14px helvetica, sans-serif;
+              background: #ddd;
+              background: -webkit-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+              background: -moz-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+              background: -ms-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+              background: -o-radial-gradient(circle,#aaa,#eee 60%) center fixed;
+              border-top: 8px solid rgba(51,51,51,.8);
+            }
+            #wrapper {
+              border-top: 1px solid #999;
+              margin-top: 160px;
+              padding: 15px;
+              background: #eee;
+              background: -webkit-linear-gradient(#fff,#ccc);
+              background: -moz-linear-gradient(#fff,#ccc);
+              background: -ms-linear-gradient(#fff,#ccc);
+              background: -o-linear-gradient(#fff,#ccc);
+              opacity: .9;
+              box-shadow: 0px 1px 8px rgba(0,0,0,0.3);
+            }
+            #inner {
+              width: 350px;
+              margin: 0 auto;
+            }
+            #button {
+              margin: 0 auto;
+              border-radius: 3px;
+              text-align: center;
+              font: 36px verdana,arial,sans-serif;
+              color: white;
+              text-shadow: 0 -1px 0 rgba(0,0,0,.8);
+              height: 70px;
+              line-height: 70px;
+              background: #555;
+              background: -webkit-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+              background: -moz-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+              background: -ms-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+              background: -o-linear-gradient(#5F5F5F,#565656 50%,#4C4C4C 51%,#373737);
+              box-shadow: inset 0 1px 3px rgba(0,0,0,0.9);
+            }
+            #button:hover {
+              cursor: pointer;
+              background: #666;
+              background: -webkit-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+              background: -moz-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+              background: -ms-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+              background: -o-linear-gradient(#707070,#666666 50%,#5B5B5B 51%,#474747);
+            }
+            #button:active {
+              box-shadow: inset 0 1px 12px rgba(0,0,0,0.9);
+              background: #444;
+            }
+            #label {
+              text-align: left;
+              text-shadow: 0 1px 1px #fff;
+              margin: 16px auto 0;
+            }
+            form {
+              height: 38px;
+              background: #fff;
+              border: 1px solid #bbb;
+              border-radius: 3px;
+              position: relative;
+            }
+            button, input {
+              font-weight: bold;
+              font-size: 15px;
+            }
+            input[type="text"] {
+              border-radius: 3px;
+              box-sizing: border-box;
+              -moz-box-sizing: border-box;   
+              padding: 0 45px 0 10px;
+              *padding: 0; /* IE7 hack */
+              width: 100%;
+              height: 100%;
+              outline: none;
+              border: none;
+              position: absolute;
+            }
+            button[type="submit"] {
+              position: absolute;
+              right: 0;
+              width: 45px;
+              height: 38px;
+            }
+            @media only screen and (min-device-width: 320px) and (max-device-width: 720px) {
+              body {
+                background: #bbb;
+                background: -webkit-linear-gradient(#aaa,#eee 60%) center fixed;
+                background: -moz-linear-gradient(#aaa,#eee 60%) center fixed;
+                background: -ms-linear-gradient(#aaa,#eee 60%) center fixed;
+              }
+              #wrapper {
+                margin-top: 0;
+              }
+              #inner {
+                width: 95%;        
+              }
+              #label {
+                text-align: center;
+              }
+            }
+        /*]]>*/
+        </style>
+        <link href="static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/> 
+        
+        <div id="wrapper">
+            <div id="inner">
+                <div id="button" onclick="go2Random()" class="translate" th:utext="#{renkanIndex.new_renkan}">New Renkan</div>
+                <div id="label" class="translate" th:text="#{renkanIndex.renkan_title}">Create a Renkan with the title</div> 
+                <form action="#" onsubmit="go2Title();return false;"> 
+                    <input type="text" id="renkantitle" autofocus="autofocus" x-webkit-speech="x-webkit-speech"/> 
+                    <button type="submit">OK</button>
+                </form>
+            </div>
+            <h2 th:text="#{renkanIndex.project_list}">Project list</h2>
+            <table>
+              <thead>
+                <tr>
+                    <th th:text="#{renkanIndex.project_name}">Name</th><th th:text="#{renkanIndex.project_creation}">Creation</th><th th:text="#{renkanIndex.project_edit}">Edit</th>
+                </tr>
+              </thead>
+              <tbody>
+                <tr th:each="project: ${projects}">
+                  <th th:text="${project.title}">title</th>
+                  <td th:text="${#dates.format(project.created, #messages.msg('date.format'))}">date</td>
+                  <td><a href="#" th:href="@{'/p/'+${project.id}(cowebkey=${project.key})}" th:text="#{renkanIndex.project_edit_link}">Edit projet</a></td>
+                </tr>
+              </tbody>
+            </table>            
+        </div>
+        <script th:inline="javascript" >
+        /*<![CDATA[*/
+      
+            function go2Title()
+            {
+                var renkantitle = $("#renkantitle").val();
+                if(renkantitle.length == 0) {
+                	var alert_message = /*[[#{renkanIndex.js.empty_name_error}]]*/"Please enter a title"; 
+                	alert(alert_message);
+                	return false;
+                }
+                
+                new_renkan = {
+                	title: renkantitle,
+                	description: "(empty description)",                	
+                	uri: null,
+                	space_id: /*[[${space.id}]]*/"_",
+                };
+                
+                var post_url = /*[[@{/rest/projects/}]]*/"/rest/projects/"; 
+                $.ajax(post_url, {
+                    data:JSON.stringify(new_renkan),
+                    type: "POST",
+                    dataType: "json",
+                    contentType: "application/json; charset=UTF-8"                    
+                }).done(function(project){
+                	var template_url = /*[[@{'/p/<%=project_id%>'(cowebkey='')}]]*/"p/<%=project_id%>?cowebkey=<%=project_key%>";
+                	window.location = _.template(template_url+'<%=project_key%>', {project_id: project.id, project_key: project.key});
+                });
+                
+                //? window.location = "p/" + renkantitle : alert(/*[[#{renkanIndex.js.empty_name_error}]]*/"Please enter a name");
+            }
+ 
+        /*]]>*/
+        </script>
+
+</html>
--- a/server/src/main/webapp/WEB-INF/templates/renkanIndex.html	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/webapp/WEB-INF/templates/renkanIndex.html	Sat Mar 09 02:19:49 2013 +0100
@@ -126,25 +126,25 @@
         
         <div id="wrapper">
             <div id="inner">
-                <div id="button" onclick="go2Random()" class="translate" th:utext="#{renkanIndex.new_renkan}">New Renkan</div>
+                <div id="button" onclick="go2Random()" class="translate" th:utext="#{renkanIndex.new_space}">New Space</div>
                 <div id="label" class="translate" th:text="#{renkanIndex.renkan_title}">Create a Renkan with the title</div> 
                 <form action="#" onsubmit="go2Title();return false;"> 
                     <input type="text" id="renkantitle" autofocus="autofocus" x-webkit-speech="x-webkit-speech"/> 
                     <button type="submit">OK</button>
                 </form>
             </div>
-            <h2 th:text="#{renkanIndex.project_list}">Project list</h2>
+            <h2 th:text="#{renkanIndex.space_list}">Space list</h2>
             <table>
               <thead>
                 <tr>
-                    <th th:text="#{renkanIndex.project_name}">Name</th><th th:text="#{renkanIndex.project_creation}">Creation</th><th th:text="#{renkanIndex.project_edit}">Edit</th>
+                    <th th:text="#{renkanIndex.space_name}">Name</th><th th:text="#{renkanIndex.space_creation}">Creation</th><th th:text="#{renkanIndex.space_open}">Edit</th>
                 </tr>
               </thead>
               <tbody>
-                <tr th:each="project: ${projects}">
-                  <th th:text="${project.title}">title</th>
-                  <td th:text="${#dates.format(project.created, #messages.msg('date.format'))}">date</td>
-                  <td><a href="#" th:href="@{'/p/'+${project.id}(cowebkey=${project.key})}" th:text="#{renkanIndex.project_edit_link}">Edit projet</a></td>
+                <tr th:each="space: ${spaces}">
+                  <th th:text="${space.title}">title</th>
+                  <td th:text="${#dates.format(space.created, #messages.msg('date.format'))}">date</td>
+                  <td><a href="#" th:href="@{'/s/'+${space.id}}" th:text="#{renkanIndex.space_open_link}">Open space</a></td>
                 </tr>
               </tbody>
             </table>            
@@ -167,15 +167,15 @@
                 	uri: null
                 };
                 
-                var post_url = /*[[@{/rest/projects/}]]*/"/rest/projects/"; 
+                var post_url = /*[[@{/rest/spaces/}]]*/"/rest/spaces/"; 
                 $.ajax(post_url, {
                     data:JSON.stringify(new_renkan),
                     type: "POST",
                     dataType: "json",
                     contentType: "application/json; charset=UTF-8"                    
-                }).done(function(project){
-                	var template_url = /*[[@{'/p/<%=project_id%>'(cowebkey='')}]]*/"p/<%=project_id%>?cowebkey=<%=project_key%>";
-                	window.location = _.template(template_url+'<%=project_key%>', {project_id: project.id, project_key: project.key});
+                }).done(function(space){
+                	var template_url = /*[[@{'/s/<%=space_id%>'}]]*/"s/<%=space_id%>";
+                	window.location = _.template(template_url, {space_id: space.id});
                 });
                 
                 //? window.location = "p/" + renkantitle : alert(/*[[#{renkanIndex.js.empty_name_error}]]*/"Please enter a name");
--- a/server/src/main/webapp/WEB-INF/web.xml	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/main/webapp/WEB-INF/web.xml	Sat Mar 09 02:19:49 2013 +0100
@@ -63,7 +63,7 @@
     <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
     <init-param>
       <param-name>com.sun.jersey.config.property.packages</param-name>
-      <param-value>org.iri_research.renkan.rest</param-value>
+      <param-value>org.iri_research.renkan.rest;com.fasterxml.jackson.jaxrs</param-value>
     </init-param>
     <init-param>
       <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
--- a/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectSyncsRepositoryTest.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectSyncsRepositoryTest.java	Sat Mar 09 02:19:49 2013 +0100
@@ -3,12 +3,15 @@
 
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.UUID;
 
 import org.iri_research.renkan.RenkanException;
 import org.iri_research.renkan.models.Project;
 import org.iri_research.renkan.models.ProjectSync;
+import org.iri_research.renkan.models.Space;
 import org.iri_research.renkan.repositories.ProjectSyncsRepository;
 import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.iri_research.renkan.repositories.SpacesRepository;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -33,6 +36,9 @@
 	@Autowired
 	private ProjectSyncsRepository projectSyncsRepository;
 	
+	@Autowired
+	private SpacesRepository spacesRepository;
+	
 	
 	private ArrayList<Project> testProjects = new ArrayList<Project>();
 	
@@ -42,10 +48,12 @@
 	@Before
 	public void setup() {
 		
-		logger.debug("Setup");		
+		logger.debug("Setup");
+		Space testSpace = new Space(UUID.randomUUID().toString(), "test", "Test space", null, null, null, "test_user", null, null);
+		testSpace = spacesRepository.save(testSpace);
 		ArrayList<Project> pl = new ArrayList<Project>();
-		pl.add(new Project(null, "test1", "desc1", "http://localhost:8080/rest/projects/id1", new Date()));
-		pl.add(new Project(null, "test2", "desc2", "http://localhost:8080/rest/projects/id2", new Date()));
+		pl.add(new Project(testSpace.getId(), null, "test1", "desc1", "http://localhost:8080/rest/projects/id1", new Date()));
+		pl.add(new Project(testSpace.getId(), null, "test2", "desc2", "http://localhost:8080/rest/projects/id2", new Date()));
 		logger.debug("Setup : new Project ");
 		for(Project p: projectRepository.save(pl)) {
 			this.testProjects.add(p);
--- a/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectsRepositoryTest.java	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectsRepositoryTest.java	Sat Mar 09 02:19:49 2013 +0100
@@ -6,7 +6,9 @@
 import java.util.UUID;
 
 import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.Space;
 import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.iri_research.renkan.repositories.SpacesRepository;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -26,7 +28,10 @@
 	private Logger logger = LoggerFactory.getLogger(ProjectsRepositoryTest.class);
 	
 	@Autowired
-	private ProjectsRepository projectRepository;
+	private ProjectsRepository projectsRepository;
+	
+	@Autowired
+	private SpacesRepository spacesRepository;
 	
 	private ArrayList<Project> testProjects = new ArrayList<Project>();
 	
@@ -38,12 +43,14 @@
 	@Before
 	public void setup() {
 		
-		logger.debug("Setup");		
+		logger.debug("Setup");
+		Space testSpace = new Space(UUID.randomUUID().toString(), "test", "Test space", null, null, null, "test_user", null, this.creationDate);
+		testSpace = spacesRepository.save(testSpace);
 		ArrayList<Project> pl = new ArrayList<Project>();
-		pl.add(new Project(UUID.randomUUID().toString(), "test1", "desc1", "http://localhost:8080/rest/projects/id1", this.creationDate));
-		pl.add(new Project(UUID.randomUUID().toString(), "test2", "desc2", "http://localhost:8080/rest/projects/id2", this.creationDate));
+		pl.add(new Project(testSpace.getId(), UUID.randomUUID().toString(), "test1", "desc1", "http://localhost:8080/rest/projects/id1", this.creationDate));
+		pl.add(new Project(testSpace.getId(), UUID.randomUUID().toString(), "test2", "desc2", "http://localhost:8080/rest/projects/id2", this.creationDate));
 		logger.debug("Setup : new Project ");
-		for(Project p: projectRepository.save(pl)) {
+		for(Project p: projectsRepository.save(pl)) {
 			this.testProjects.add(p);
 		}
 	}
@@ -51,13 +58,13 @@
 	@After
 	public void teardown() {
 		logger.debug("Teardown");
-		projectRepository.deleteAll();
+		projectsRepository.deleteAll();
 	}
 	
 	@Test
 	public void testInitialRevCounter() {
 		
-		Project p = projectRepository.findOne(this.testProjects.get(0).getId());
+		Project p = projectsRepository.findOne(this.testProjects.get(0).getId());
 		
 		Assert.assertEquals("Initial rev counter should be 1", 1, p.getRevCounter());
 	}
@@ -65,22 +72,22 @@
 	@Test
 	public void testIncrementRevCounter() {
 		
-		int revCounter = projectRepository.getRevCounter(this.testProjects.get(0).getId());
+		int revCounter = projectsRepository.getRevCounter(this.testProjects.get(0).getId());
 		Assert.assertEquals("After 1 call rev counter should be 1", 1, revCounter);
-		revCounter = projectRepository.getRevCounter(this.testProjects.get(0).getId());
+		revCounter = projectsRepository.getRevCounter(this.testProjects.get(0).getId());
 		Assert.assertEquals("After 2 calls rev counter should be 2", 2, revCounter);
 
 		for(int i=0; i<10; i++) {
-			revCounter = projectRepository.getRevCounter(this.testProjects.get(0).getId());
+			revCounter = projectsRepository.getRevCounter(this.testProjects.get(0).getId());
 		}
 		
 		Assert.assertEquals("After 10 more calls rev counter should be 12", 12, revCounter);
 		
-		Project p = projectRepository.findOne(this.testProjects.get(0).getId());
+		Project p = projectsRepository.findOne(this.testProjects.get(0).getId());
 		
 		Assert.assertEquals("next rev counter should be 13", 13, p.getRevCounter());
 		
-		p = projectRepository.findOne(this.testProjects.get(1).getId());
+		p = projectsRepository.findOne(this.testProjects.get(1).getId());
 		
 		Assert.assertEquals("other project next rev counter should be 1", 1, p.getRevCounter());
 		
@@ -90,7 +97,7 @@
 	@Test
 	public void testIncrementNonExisting() {
 		
-		int revCounter = projectRepository.getRevCounter("aaaa");
+		int revCounter = projectsRepository.getRevCounter("aaaa");
 		Assert.assertEquals("Rev counter non existing == -1", -1, revCounter);
 		
 	}
@@ -98,7 +105,7 @@
 	@Test
 	public void testIncrementNull() {
 		
-		int revCounter = projectRepository.getRevCounter(null);
+		int revCounter = projectsRepository.getRevCounter(null);
 		Assert.assertEquals("Rev counter null == -1", -1, revCounter);
 		
 	}
@@ -106,7 +113,7 @@
 	@Test
 	public void testIncrementEmpty() {
 		
-		int revCounter = projectRepository.getRevCounter("");
+		int revCounter = projectsRepository.getRevCounter("");
 		Assert.assertEquals("Rev counter empty == -1", -1, revCounter);
 		
 	}
@@ -114,7 +121,7 @@
 	@Test
 	public void testDateCreation() {
 		
-		for (Project p : projectRepository.findAll()) {
+		for (Project p : projectsRepository.findAll()) {
 			Assert.assertEquals(this.creationDate, p.getCreated());
 		} 
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/SpacesRepositoryTest.java	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,99 @@
+package org.iri_research.renkan.test.repositories;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.iri_research.renkan.models.Space;
+import org.iri_research.renkan.repositories.SpacesRepository;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("repositories-context.xml")
+public class SpacesRepositoryTest {
+	
+	private Logger logger = LoggerFactory.getLogger(SpacesRepositoryTest.class);
+	
+	@Autowired
+	private SpacesRepository spacesRepository;
+
+	@Autowired
+	private MongoTemplate mongoTemplate;
+	
+	private Map<String, Space> spacesList = new HashMap<String, Space>();
+
+	
+	@Before
+	public void setup() {
+		
+		logger.debug("Setup");
+		spacesRepository.deleteAll();
+		Date creationDate = new Date();
+		String uuid = UUID.randomUUID().toString();
+		Space testSpace = new Space(uuid, "test", "Test space", "{}", "http://ldt.iri.centrepompidou.fr", "#ababab", "test_user", "http://ldt.iri.centrepompidou.fr", creationDate);
+		testSpace = spacesRepository.save(testSpace);
+		this.spacesList.put(uuid, testSpace);
+	}
+	
+	@Test
+	public void testFieldMapping() {
+		// query json directly with mongodb driver
+		// check field values
+		DBCollection coll = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Space.class));
+		
+		for(DBObject obj: coll.find()) {
+			Assert.assertTrue("mongo object must have _id field", obj.containsField("_id"));
+
+			String id = obj.get("_id").toString();
+			
+			Space sp = this.spacesList.get(id);
+			
+			Assert.assertTrue("mongo object must have title field", obj.containsField("title"));
+			Assert.assertEquals("Titles must be the same", obj.get("title"), sp.getTitle());
+
+			Assert.assertTrue("mongo object must have description field", obj.containsField("description"));
+			Assert.assertEquals("description must be the same", obj.get("description"), sp.getDescription());
+
+			Assert.assertTrue("mongo object must have color field", obj.containsField("color"));
+			Assert.assertEquals("Color must be the same", obj.get("color"), sp.getColor());
+
+			Assert.assertTrue("mongo object must have uri field", obj.containsField("uri"));
+			Assert.assertEquals("Uri must be the same", obj.get("uri"), sp.getUri());
+
+			Assert.assertTrue("mongo object must have image field", obj.containsField("image"));
+			Assert.assertEquals("Image must be the same", obj.get("image"), sp.getImage());
+			
+			Assert.assertTrue("mongo object must have created field", obj.containsField("created"));
+			Assert.assertEquals("Created must be the same", obj.get("created"), sp.getCreated());
+
+			Assert.assertTrue("mongo object must have bin_config field", obj.containsField("bin_config"));
+			Assert.assertEquals("Uri must be the same", obj.get("bin_config"), sp.getBinConfig());
+
+			Assert.assertTrue("mongo object must have created_by field", obj.containsField("created_by"));
+			Assert.assertEquals("created by must be the same", obj.get("created_by"), sp.getCreatedBy());			
+			
+		}
+		
+	}
+	
+	@After
+	public void teardown() {
+		spacesRepository.deleteAll();
+	}
+
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/rest/SpaceRestTest.java	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,721 @@
+package org.iri_research.renkan.test.rest;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
+
+import junit.framework.Assert;
+
+import org.iri_research.renkan.models.Space;
+import org.iri_research.renkan.repositories.SpacesRepository;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.ISODateTimeFormat;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.context.ContextLoaderListener;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.sun.jersey.api.client.ClientHandlerException;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
+import com.sun.jersey.test.framework.AppDescriptor;
+import com.sun.jersey.test.framework.JerseyTest;
+import com.sun.jersey.test.framework.WebAppDescriptor;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("rest-context.xml")
+public class SpaceRestTest extends JerseyTest {
+	
+	private Logger logger = LoggerFactory.getLogger(SpaceRestTest.class);
+	
+	@Autowired
+	private SpacesRepository spacesRepository;
+		
+	private Map<String,Space> spacesList = new HashMap<String, Space>();
+	private String firstSpaceUUID = null;
+		
+
+	public SpaceRestTest() {
+	}
+	
+	@Override
+	protected AppDescriptor configure() {
+		return new WebAppDescriptor.Builder("org.iri_research.renkan.rest")
+			.contextPath("rest")
+			.contextParam("contextConfigLocation", "classpath:/org/iri_research/renkan/test/rest/rest-context.xml")
+			.initParam("com.sun.jersey.config.property.packages", "org.iri_research.renkan.rest;com.fasterxml.jackson.jaxrs")
+			.servletClass(SpringServlet.class)
+			.contextListenerClass(ContextLoaderListener.class)
+			.build();
+	};
+	
+	@Before
+	public void setup() {
+		
+		logger.debug("Setup");
+		spacesRepository.deleteAll();
+		Date creationDate = new Date();
+		this.firstSpaceUUID = UUID.randomUUID().toString();
+		Space testSpace = new Space(firstSpaceUUID, "test", "Test space", "{}", "http://ldt.iri.centrepompidou.fr", "#ababab", "test_user", "http://ldt.iri.centrepompidou.fr", creationDate);
+		testSpace = spacesRepository.save(testSpace);
+		this.spacesList.put(firstSpaceUUID, testSpace);
+	}
+	
+	@After
+	public void teardown() {
+		//spacesRepository.deleteAll();
+	}
+
+	
+	@Test
+	public void testSetup() throws JsonProcessingException, IOException {
+
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		
+		Assert.assertNotNull("The response string for the list of spaces must not be null", respString);
+		
+		logger.debug("RESPONSE : " + respString);
+		
+		Assert.assertTrue("The length of the space list resp. string must be > 0", respString.length() > 0);
+		
+		
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		Assert.assertTrue("The spaceList must be an array", spacesList.isArray());
+		Assert.assertEquals("The spaceList length must be = " + this.spacesList.size(), this.spacesList.size(), spacesList.size());
+		
+		for (JsonNode jsonNode : spacesList) {
+			Assert.assertTrue("the space must have an id", jsonNode.hasNonNull("id"));
+			String id = jsonNode.get("id").asText();
+			Assert.assertTrue("The id must be in the spacesList", this.spacesList.containsKey(id));
+			Space space = this.spacesList.get(id);
+			Assert.assertNotNull("The object must in the spacesList must not be null", space);
+								
+		}
+		
+	}
+	
+	@Test
+	public void testTitle() throws JsonProcessingException, IOException {
+		
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		for (JsonNode jsonNode : spacesList) {
+			String id = jsonNode.get("_id").asText();
+			Space space = this.spacesList.get(id);
+			
+			Assert.assertTrue("the space must have a title", jsonNode.hasNonNull("title"));
+			String title = jsonNode.get("title").asText();
+			Assert.assertEquals("space title must be equals to " + space.getTitle(), space.getTitle(), title);
+		}
+
+	}
+
+	@Test
+	public void testDescription() throws JsonProcessingException, IOException {
+		
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		for (JsonNode jsonNode : spacesList) {
+			String id = jsonNode.get("id").asText();
+			Space space = this.spacesList.get(id);
+			
+			Assert.assertTrue("the space must have a description", jsonNode.hasNonNull("description"));
+			String description = jsonNode.get("description").asText();
+			Assert.assertEquals("space description must be equals to " + space.getDescription(), space.getDescription(), description);
+		}
+
+	}
+
+	@Test
+	public void testUri() throws JsonProcessingException, IOException {
+		
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		for (JsonNode jsonNode : spacesList) {
+			String id = jsonNode.get("id").asText();
+			Space space = this.spacesList.get(id);
+			
+			Assert.assertTrue("the space must have a uri", jsonNode.hasNonNull("uri"));
+			String uri = jsonNode.get("uri").asText();
+			Assert.assertEquals("space uri must be equals to " + space.getUri(), space.getUri(), uri);
+		}
+
+	}
+
+	@Test
+	public void testColor() throws JsonProcessingException, IOException {
+		
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		for (JsonNode jsonNode : spacesList) {
+			String id = jsonNode.get("id").asText();
+			Space space = this.spacesList.get(id);
+			
+			Assert.assertTrue("the space must have a color", jsonNode.hasNonNull("color"));
+			String color = jsonNode.get("color").asText();
+			Assert.assertEquals("space color must be equals to " + space.getColor(), space.getColor(), color);
+		}
+
+	}
+
+	
+	
+	@Test
+	public void testBinConfig() throws JsonProcessingException, IOException {
+		
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		for (JsonNode jsonNode : spacesList) {
+			String id = jsonNode.get("id").asText();
+			Space space = this.spacesList.get(id);
+			
+			Assert.assertTrue("the space must have a bin_config", jsonNode.hasNonNull("bin_config"));
+			String binConfig = jsonNode.get("bin_config").asText();
+			Assert.assertEquals("space bin_config must be equals to " + space.getBinConfig(), space.getBinConfig(), binConfig);
+		}
+
+	}
+	
+	@Test
+	public void testCreatedBy() throws JsonProcessingException, IOException {
+		
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		for (JsonNode jsonNode : spacesList) {
+			String id = jsonNode.get("id").asText();
+			Space space = this.spacesList.get(id);
+			
+			Assert.assertTrue("the space must have a created_by", jsonNode.hasNonNull("created_by"));
+			String createdBy = jsonNode.get("created_by").asText();
+			Assert.assertEquals("space created_by must be equals to " + space.getCreatedBy(), space.getCreatedBy(), createdBy);
+		}
+
+	}
+	
+	
+	@Test
+	public void testCreated() throws JsonProcessingException, IOException {
+		
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		for (JsonNode jsonNode : spacesList) {
+			String id = jsonNode.get("id").asText();
+			Space space = this.spacesList.get(id);
+			
+			Assert.assertTrue("the space must have a created", jsonNode.hasNonNull("created"));
+			
+			String dateStr = jsonNode.get("created").asText();
+			
+			DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+			DateTime date = fmt.parseDateTime(dateStr);
+			
+			Assert.assertEquals("Created date must be the same", space.getCreated(), date.toDate());				
+			
+		}
+
+	}
+	
+	@Test
+	public void testImage() throws JsonProcessingException, IOException {
+		
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode spacesList = mapper.readTree(respString);
+		
+		for (JsonNode jsonNode : spacesList) {
+			String id = jsonNode.get("id").asText();
+			Space space = this.spacesList.get(id);
+			
+			Assert.assertTrue("the space must have a image", jsonNode.hasNonNull("image"));
+			String image = jsonNode.get("image").asText();
+			Assert.assertEquals("space image must be equals to " + space.getImage(), space.getImage(), image);
+		}
+
+	}
+	
+	@Test
+	public void testSingleCreated() throws JsonProcessingException, IOException {
+		
+		Space space = this.spacesList.get(this.firstSpaceUUID);
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode jsonNode = mapper.readTree(respString);
+		
+		String id = jsonNode.get("id").asText();
+		Assert.assertEquals("id must be equals", space.getId(), id);
+		
+		Assert.assertTrue("the space must have a created", jsonNode.hasNonNull("created"));
+		
+		String dateStr = jsonNode.get("created").asText();
+		
+		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+		DateTime date = fmt.parseDateTime(dateStr);
+		
+		Assert.assertEquals("Created date must be the same", space.getCreated(), date.toDate());				
+
+	}
+	
+	@Test
+	public void testSingleTitle() throws JsonProcessingException, IOException {
+		
+		Space space = this.spacesList.get(this.firstSpaceUUID);
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode jsonNode = mapper.readTree(respString);
+					
+		Assert.assertTrue("the space must have a title", jsonNode.hasNonNull("title"));
+		String title = jsonNode.get("title").asText();
+		Assert.assertEquals("space title must be equals to " + space.getTitle(), space.getTitle(), title);
+	}
+
+	@Test
+	public void testSingleDescription() throws JsonProcessingException, IOException {
+		
+		Space space = this.spacesList.get(this.firstSpaceUUID);
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode jsonNode = mapper.readTree(respString);
+					
+		Assert.assertTrue("the space must have a description", jsonNode.hasNonNull("description"));
+		String description = jsonNode.get("description").asText();
+		Assert.assertEquals("space description must be equals to " + space.getDescription(), space.getDescription(), description);
+	}
+
+	@Test
+	public void testSingleUri() throws JsonProcessingException, IOException {
+		
+		Space space = this.spacesList.get(this.firstSpaceUUID);
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode jsonNode = mapper.readTree(respString);
+		
+		Assert.assertTrue("the space must have a uri", jsonNode.hasNonNull("uri"));
+		String uri = jsonNode.get("uri").asText();
+		Assert.assertEquals("space uri must be equals to " + space.getUri(), space.getUri(), uri);
+	}
+
+	@Test
+	public void testSingleColor() throws JsonProcessingException, IOException {
+		
+		Space space = this.spacesList.get(this.firstSpaceUUID);
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode jsonNode = mapper.readTree(respString);
+					
+		Assert.assertTrue("the space must have a color", jsonNode.hasNonNull("color"));
+		String color = jsonNode.get("color").asText();
+		Assert.assertEquals("space color must be equals to " + space.getColor(), space.getColor(), color);
+	}
+
+	
+	
+	@Test
+	public void testSingleBinConfig() throws JsonProcessingException, IOException {
+		
+		Space space = this.spacesList.get(this.firstSpaceUUID);
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode jsonNode = mapper.readTree(respString);
+		
+		Assert.assertTrue("the space must have a bin_config", jsonNode.hasNonNull("bin_config"));
+		String binConfig = jsonNode.get("bin_config").asText();
+		Assert.assertEquals("space bin_config must be equals to " + space.getBinConfig(), space.getBinConfig(), binConfig);
+	}
+	
+	@Test
+	public void testSingleCreatedBy() throws JsonProcessingException, IOException {
+		
+		Space space = this.spacesList.get(this.firstSpaceUUID);
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode jsonNode = mapper.readTree(respString);
+		
+		Assert.assertTrue("the space must have a created_by", jsonNode.hasNonNull("created_by"));
+		String createdBy = jsonNode.get("created_by").asText();
+		Assert.assertEquals("space created_by must be equals to " + space.getCreatedBy(), space.getCreatedBy(), createdBy);
+	}
+	
+		
+	@Test
+	public void testSingleImage() throws JsonProcessingException, IOException {
+	
+		Space space = this.spacesList.get(this.firstSpaceUUID);
+		WebResource webResource = this.resource();
+		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
+		logger.debug("RESPONSE : " + respString);
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode jsonNode = mapper.readTree(respString);
+					
+		Assert.assertTrue("the space must have a image", jsonNode.hasNonNull("image"));
+		String image = jsonNode.get("image").asText();
+		Assert.assertEquals("space image must be equals to " + space.getImage(), space.getImage(), image);
+	}
+	
+	
+	@Test
+	public void testPost() throws JsonProcessingException, ClientHandlerException, UniformInterfaceException, IOException {
+		
+		String title = "test_post";
+		String description = "test space post";
+		String uri = "http://ldt.iri.centrepompidou.fr/test_post";
+		String color = "#bcbcbc";
+		String image = "http://ldt.iri.centrepompidou.fr/test_post/image";
+		String created = "2013-01-01T01:01:01.001+0000";
+		String bin_config = "{name: 'test_post_config'}";
+		String created_by = "test_user_post";
+		
+		String spaceJson = String.format("{" +
+				"\"title\":\"%s\"," +
+				"\"description\":\"%s\"," +
+				"\"uri\":\"%s\"," +
+				"\"color\":\"%s\"," +
+				"\"image\":\"%s\"," +
+				"\"created\":\"%s\"," +
+				"\"bin_config\":\"%s\"," +
+				"\"created_by\":\"%s\"" +
+				"}",
+				title,
+				description,
+				uri,
+				color,
+				image,
+				created,
+				bin_config,
+				created_by);
+		
+		WebResource webResource = this.resource();
+		ClientResponse resp = webResource.path("spaces").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).post(ClientResponse.class);
+		
+		String respStr = resp.getEntity(String.class);
+		
+		Assert.assertEquals("Resp status = created : " + respStr, Status.CREATED.getStatusCode(), resp.getStatus());
+		Assert.assertTrue("Resp must be application/json", resp.getType().isCompatible(MediaType.APPLICATION_JSON_TYPE));		
+		
+		ObjectMapper mapper = new ObjectMapper();
+		JsonNode objNode = mapper.readTree(respStr);
+
+		Assert.assertTrue("the space must have an id", objNode.hasNonNull("id"));
+		String idStr = objNode.get("id").asText();
+		Assert.assertFalse("The id str must not be empty", idStr.length()==0);
+		
+		Assert.assertTrue("the space must have a title", objNode.hasNonNull("title"));
+		String titleStr = objNode.get("title").asText();
+		Assert.assertEquals("space title must be equals to " + title, title, titleStr);
+
+		Assert.assertTrue("the space must have a description", objNode.hasNonNull("description"));
+		String descriptionStr = objNode.get("description").asText();
+		Assert.assertEquals("space description must be equals to " + description, description, descriptionStr);
+
+		Assert.assertTrue("the space must have a uri", objNode.hasNonNull("uri"));
+		String uriStr = objNode.get("uri").asText();
+		Assert.assertEquals("space uri must be equals to " + uri, uri, uriStr);
+
+		Assert.assertTrue("the space must have a color", objNode.hasNonNull("color"));
+		String colorStr = objNode.get("color").asText();
+		Assert.assertEquals("space color must be equals to " + color, color, colorStr);
+
+		Assert.assertTrue("the space must have a bin_config", objNode.hasNonNull("bin_config"));
+		String bin_configStr = objNode.get("bin_config").asText();
+		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, bin_configStr);
+
+		Assert.assertTrue("the space must have a created_by", objNode.hasNonNull("created_by"));
+		String created_byStr = objNode.get("created_by").asText();
+		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, created_byStr);
+		
+		Assert.assertTrue("the space must have a created", objNode.hasNonNull("created"));
+		String createdStr = objNode.get("created").asText();
+		Assert.assertEquals("space created must be equals to " + created, created, createdStr);
+		
+		// object must be created
+		Space sp = this.spacesRepository.findOne(idStr);
+		
+		Assert.assertNotNull("Space object must be in rep", sp);
+		
+		Assert.assertEquals("space title must be equals to " + title, title, sp.getTitle());
+		Assert.assertEquals("space description must be equals to " + description, description, sp.getDescription());
+		Assert.assertEquals("space uri must be equals to " + uri, uri, sp.getUri());
+		Assert.assertEquals("space color must be equals to " + color, color, sp.getColor());
+		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, sp.getBinConfig());
+		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, sp.getCreatedBy());
+		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+		DateTime created_date = fmt.parseDateTime(created);
+		Assert.assertEquals("space created must be equals to " + created, created_date.toDate(), sp.getCreated());
+		
+	}
+
+	
+	@Test
+	public void testPostWithId() {
+		
+		String id = UUID.randomUUID().toString();
+		String title = "test_post";
+		String description = "test space post";
+		String uri = "http://ldt.iri.centrepompidou.fr/test_post";
+		String color = "#bcbcbc";
+		String image = "http://ldt.iri.centrepompidou.fr/test_post/image";
+		String created = "2013-01-01T01:01:01.001+0000";
+		String bin_config = "{name: 'test_post_config'}";
+		String created_by = "test_user_post";
+		
+		String spaceJson = String.format("{" +
+		        "\"id\":\"%s\"," +
+				"\"title\":\"%s\"," +
+				"\"description\":\"%s\"," +
+				"\"uri\":\"%s\"," +
+				"\"color\":\"%s\"," +
+				"\"image\":\"%s\"," +
+				"\"created\":\"%s\"," +
+				"\"bin_config\":\"%s\"," +
+				"\"created_by\":\"%s\"" +
+				"}",
+				id,
+				title,
+				description,
+				uri,
+				color,
+				image,
+				created,
+				bin_config,
+				created_by);
+		
+		WebResource webResource = this.resource();
+		ClientResponse resp = webResource.path("spaces").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).post(ClientResponse.class);
+		
+		String respStr = resp.getEntity(String.class);
+		
+		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+		Assert.assertEquals("Error message", "Id in JSON must be null", respStr);
+		
+	}
+		
+	@Test
+	public void testPut() throws JsonProcessingException, IOException {
+		
+		String id = this.firstSpaceUUID;
+		String title = "test_post";
+		String description = "test space put";
+		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
+		String color = "#bcbcbc";
+		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
+		String created = "2013-01-01T01:01:01.001+0000";
+		String bin_config = "{name: 'test_put_config'}";
+		String created_by = "test_user_put";
+		
+		String spaceJson = String.format("{" +
+		        "\"id\":\"%s\"," +
+				"\"title\":\"%s\"," +
+				"\"description\":\"%s\"," +
+				"\"uri\":\"%s\"," +
+				"\"color\":\"%s\"," +
+				"\"image\":\"%s\"," +
+				"\"created\":\"%s\"," +
+				"\"bin_config\":\"%s\"," +
+				"\"created_by\":\"%s\"" +
+				"}",
+				id,
+				title,
+				description,
+				uri,
+				color,
+				image,
+				created,
+				bin_config,
+				created_by);
+		
+		WebResource webResource = this.resource();
+		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
+		
+		String respStr = "";
+		
+		if(resp.getStatus() != 204) {
+			respStr = resp.getEntity(String.class);
+		}
+		
+		Assert.assertEquals("Resp status = created : " + respStr, Status.NO_CONTENT.getStatusCode(), resp.getStatus());
+		Assert.assertNull("Resp type must be null", resp.getType());		
+
+		
+		// object must be updated
+		Space sp = this.spacesRepository.findOne(id);
+		
+		Assert.assertNotNull("Space object must be in rep", sp);
+		
+		Assert.assertEquals("space title must be equals to " + title, title, sp.getTitle());
+		Assert.assertEquals("space description must be equals to " + description, description, sp.getDescription());
+		Assert.assertEquals("space uri must be equals to " + uri, uri, sp.getUri());
+		Assert.assertEquals("space color must be equals to " + color, color, sp.getColor());
+		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, sp.getBinConfig());
+		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, sp.getCreatedBy());
+		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+		DateTime created_date = fmt.parseDateTime(created);
+		Assert.assertEquals("space created must be equals to " + created, created_date.toDate(), sp.getCreated());
+
+	}
+	
+	@Test
+	public void testPutWithoutId() {
+
+		String title = "test_put";
+		String description = "test space put";
+		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
+		String color = "#bcbcbc";
+		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
+		String created = "2013-01-01T01:01:01.001+0000";
+		String bin_config = "{name: 'test_put_config'}";
+		String created_by = "test_user_put";
+		
+		String spaceJson = String.format("{" +
+				"\"title\":\"%s\"," +
+				"\"description\":\"%s\"," +
+				"\"uri\":\"%s\"," +
+				"\"color\":\"%s\"," +
+				"\"image\":\"%s\"," +
+				"\"created\":\"%s\"," +
+				"\"bin_config\":\"%s\"," +
+				"\"created_by\":\"%s\"" +
+				"}",
+				title,
+				description,
+				uri,
+				color,
+				image,
+				created,
+				bin_config,
+				created_by);
+		
+		WebResource webResource = this.resource();
+		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
+		
+		String respStr = resp.getEntity(String.class);
+		
+		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+		Assert.assertEquals("Error message", "Id parameter and id in JSON do not match", respStr);		
+	}
+	
+	@Test
+	public void testPutBadId() {
+		
+		String id = UUID.randomUUID().toString();
+		String title = "test_post";
+		String description = "test space put";
+		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
+		String color = "#bcbcbc";
+		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
+		String created = "2013-01-01T01:01:01.001+0000";
+		String bin_config = "{name: 'test_put_config'}";
+		String created_by = "test_user_put";
+		
+		String spaceJson = String.format("{" +
+		        "\"id\":\"%s\"," +
+				"\"title\":\"%s\"," +
+				"\"description\":\"%s\"," +
+				"\"uri\":\"%s\"," +
+				"\"color\":\"%s\"," +
+				"\"image\":\"%s\"," +
+				"\"created\":\"%s\"," +
+				"\"bin_config\":\"%s\"," +
+				"\"created_by\":\"%s\"" +
+				"}",
+				id,
+				title,
+				description,
+				uri,
+				color,
+				image,
+				created,
+				bin_config,
+				created_by);
+		
+		WebResource webResource = this.resource();
+		ClientResponse resp = webResource.path("spaces").path(id).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
+		
+		String respStr = resp.getEntity(String.class);
+		
+		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.NOT_FOUND.getStatusCode(), resp.getStatus());
+		
+	}
+	
+	@Test
+	public void testDelete() {
+
+		WebResource webResource = this.resource();
+		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.TEXT_PLAIN).delete(ClientResponse.class);
+		
+		String respStr = resp.getEntity(String.class);
+		URI reqUri = webResource.getUriBuilder().path("spaces").path(this.firstSpaceUUID).build();
+
+		Assert.assertEquals("Status must be deleted : " + respStr, Status.OK.getStatusCode(), resp.getStatus());
+		Assert.assertEquals(String.format("Message must be \"%s deleted\"", reqUri), String.format("%s deleted",reqUri) , respStr);
+		
+		// object must be updated
+		Space sp = this.spacesRepository.findOne(this.firstSpaceUUID);
+		
+		Assert.assertNull("Space object must be in rep", sp);
+
+	}
+}
--- a/server/src/test/resources/org/iri_research/renkan/test/repositories/mongo-config.xml	Fri Mar 01 19:14:30 2013 +0100
+++ b/server/src/test/resources/org/iri_research/renkan/test/repositories/mongo-config.xml	Sat Mar 09 02:19:49 2013 +0100
@@ -19,7 +19,7 @@
 	<!-- Offers convenience methods and automatic mapping between MongoDB JSON documents and your domain classes. -->
   	<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
   	    <constructor-arg ref="mongo"/>
-  		<constructor-arg value="renkan_test"/>
+  		<constructor-arg value="renkan_repo_test"/>
   		<property name="writeResultChecking" value="EXCEPTION"/>
   	</bean>
   	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/resources/org/iri_research/renkan/test/rest/mongo-config.xml	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+	xmlns:p="http://www.springframework.org/schema/p" 
+    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
+    xmlns:context="http://www.springframework.org/schema/context"
+    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans 
+	   		http://www.springframework.org/schema/beans/spring-beans.xsd
+   			http://www.springframework.org/schema/data/mongo
+    		http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
+    		http://www.springframework.org/schema/context
+            http://www.springframework.org/schema/context/spring-context.xsd
+            http://www.springframework.org/schema/data/jpa
+            http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">	
+	<!-- Default bean name is 'mongo' -->
+	<mongo:mongo host="localhost" port="27017"/>
+		
+	<!-- Offers convenience methods and automatic mapping between MongoDB JSON documents and your domain classes. -->
+  	<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
+  	    <constructor-arg ref="mongo"/>
+  		<constructor-arg value="renkan_rest_test"/>
+  		<property name="writeResultChecking" value="EXCEPTION"/>
+  	</bean>
+  	
+  	<mongo:repositories base-package="org.iri_research.renkan" factory-class="org.iri_research.renkan.repositories.RenkanRepositoryFactoryBean" />
+  	  	
+</beans>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/resources/org/iri_research/renkan/test/rest/rest-context.xml	Sat Mar 09 02:19:49 2013 +0100
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+    xmlns:context="http://www.springframework.org/schema/context"
+    xsi:schemaLocation="http://www.springframework.org/schema/beans 
+            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+            http://www.springframework.org/schema/context
+            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+    
+    <!-- Activates various annotations to be detected in bean classes -->
+    <context:annotation-config />
+    
+    <!-- Configures the annotation-driven Spring MVC Controller programming model.
+    Note that, with Spring 3.0, this tag works in Servlet MVC only!  -->
+
+    <!-- Loads MongoDB configuraton -->
+    <import resource="mongo-config.xml"/>
+
+    <!--bean id="bayeuxServer" class="org.cometd.server.BayeuxServerImpl" init-method="start" destroy-method="stop">
+        <property name="options">
+            <map>
+                <entry key="logLevel" value="3" />
+                <entry key="timeout" value="15000" />
+            </map>
+        </property>  
+    </bean-->
+    <bean id="springConfigurer"
+        class="org.iri_research.renkan.coweb.SpringConfigurer"
+        factory-method="getInstance" />
+    
+    <!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
+     For example @Controller and @Service. Make sure to set the correct base-package-->
+    <context:component-scan base-package="org.iri_research.renkan.rest" />
+    <context:component-scan base-package="org.iri_research.renkan.coweb" />
+
+</beans>
\ No newline at end of file