diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 18fee16f..6b6b6813 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -8,5 +8,6 @@
+
\ No newline at end of file
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
new file mode 100644
index 00000000..054a1826
--- /dev/null
+++ b/.idea/sqldialects.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 00000000..9a9afd39
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,1127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Android Lint
+
+
+ Class structure
+
+
+ Declaration redundancy
+
+
+ Error handling
+
+
+ Google Web Toolkit issues
+
+
+ Inheritance issues
+
+
+ JPA issues
+
+
+ Javadoc issues
+
+
+ Plugin DevKit
+
+
+ Serialization issues
+
+
+ TestNG
+
+
+
+
+ JpaDataSourceORMInspection
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C:\Users\Ben\AppData\Roaming\Subversion
+ false
+
+
+
+
+ 1376338294825
+ 1376338294825
+
+
+ 1376338596442
+ 1376338596442
+
+
+ 1376348212505
+ 1376348212505
+
+
+ 1376351083188
+ 1376351083188
+
+
+ 1376351634915
+ 1376351634915
+
+
+ 1376353998708
+ 1376353998708
+
+
+ 1376354452508
+ 1376354452508
+
+
+ 1376417301069
+ 1376417301069
+
+
+ 1376418028240
+ 1376418028240
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ docs-web:war
+
+
+
+
+
+
+
+
+
+
+
+
+ JPA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.7
+
+
+
+
+
+
+
+
+
+
+
+ docs-web-common
+
+
+
+
+
+
+
+
+
+
+
+ 1.7
+
+
+
+
+
+
+
+
+
+
+
+ Maven: antlr:antlr:2.7.7
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/FileShare.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/FileShare.java
new file mode 100644
index 00000000..032b2a3e
--- /dev/null
+++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/FileShare.java
@@ -0,0 +1,83 @@
+package com.sismics.docs.core.model.jpa;
+
+import com.google.common.base.Objects;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Date;
+
+/**
+ * File share.
+ *
+ * @author bgamard
+ */
+@Entity
+@Table(name = "T_FILESHARE")
+public class FileShare {
+ /**
+ * File share ID.
+ */
+ @Id
+ @Column(name = "FSH_ID_C", length = 36)
+ private String id;
+
+ /**
+ * File ID.
+ */
+ @Column(name = "FSH_IDFILE_C", nullable = false, length = 36)
+ private String fileId;
+
+ /**
+ * Creation date.
+ */
+ @Column(name = "FSH_CREATEDATE_D", nullable = false)
+ private Date createDate;
+
+ /**
+ * Deletion date.
+ */
+ @Column(name = "FSH_DELETEDATE_D")
+ private Date deleteDate;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFileId() {
+ return fileId;
+ }
+
+ public void setFileId(String fileId) {
+ this.fileId = fileId;
+ }
+
+ public Date getCreateDate() {
+ return createDate;
+ }
+
+ public void setCreateDate(Date createDate) {
+ this.createDate = createDate;
+ }
+
+ public Date getDeleteDate() {
+ return deleteDate;
+ }
+
+ public void setDeleteDate(Date deleteDate) {
+ this.deleteDate = deleteDate;
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .add("id", id)
+ .add("tagId", fileId)
+ .toString();
+ }
+}
diff --git a/docs-core/src/main/resources/META-INF/persistence.xml b/docs-core/src/main/resources/META-INF/persistence.xml
index 9c684e78..2a985b15 100644
--- a/docs-core/src/main/resources/META-INF/persistence.xml
+++ b/docs-core/src/main/resources/META-INF/persistence.xml
@@ -15,5 +15,6 @@
com.sismics.docs.core.model.jpa.Document
com.sismics.docs.core.model.jpa.Tag
com.sismics.docs.core.model.jpa.DocumentTag
+ com.sismics.docs.core.model.jpa.FileShare
\ No newline at end of file
diff --git a/docs-core/src/main/resources/config.properties b/docs-core/src/main/resources/config.properties
index 53e95e79..03d382c6 100644
--- a/docs-core/src/main/resources/config.properties
+++ b/docs-core/src/main/resources/config.properties
@@ -1 +1 @@
-db.version=3
\ No newline at end of file
+db.version=4
\ No newline at end of file
diff --git a/docs-core/src/main/resources/db/update/dbupdate-004-0.sql b/docs-core/src/main/resources/db/update/dbupdate-004-0.sql
new file mode 100644
index 00000000..641e7b09
--- /dev/null
+++ b/docs-core/src/main/resources/db/update/dbupdate-004-0.sql
@@ -0,0 +1 @@
+create cached table T_FILESHARE ( FSH_ID_C varchar(36) not null, FSH_IDFILE_C varchar(36) not null, FSH_CREATEDATE_D datetime, FSH_DELETEDATE_D datetime, primary key (FSH_ID_C) );
\ No newline at end of file
diff --git a/docs-web/src/dev/resources/config.properties b/docs-web/src/dev/resources/config.properties
index a7a2e43f..299540e8 100644
--- a/docs-web/src/dev/resources/config.properties
+++ b/docs-web/src/dev/resources/config.properties
@@ -1,3 +1,3 @@
api.current_version=${project.version}
api.min_version=1.0
-db.version=3
\ No newline at end of file
+db.version=4
\ No newline at end of file
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java
index cc0c36bc..8a2e78c9 100644
--- a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java
@@ -57,6 +57,7 @@ public class FileResource extends BaseResource {
File fileDb;
try {
fileDb = fileDao.getFile(id);
+ // TODO Check that the current user owns the document linked to this file
} catch (NoResultException e) {
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id));
}
@@ -243,6 +244,7 @@ public class FileResource extends BaseResource {
File file;
try {
file = fileDao.getFile(id);
+ // TODO Check that the current user owns the document linked to this file
} catch (NoResultException e) {
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id));
}
@@ -278,6 +280,7 @@ public class FileResource extends BaseResource {
File file;
try {
file = fileDao.getFile(id);
+ // TODO Check that the current user owns the document linked to this file
} catch (NoResultException e) {
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id));
}
diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileShareResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileShareResource.java
new file mode 100644
index 00000000..96edc56e
--- /dev/null
+++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileShareResource.java
@@ -0,0 +1,91 @@
+package com.sismics.docs.rest.resource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+
+import com.sismics.rest.exception.ForbiddenClientException;
+import com.sismics.rest.util.ValidationUtil;
+import com.sun.jersey.multipart.FormDataParam;
+
+/**
+ * File share REST resources.
+ *
+ * @author bgamard
+ */
+@Path("/share")
+public class FileShareResource extends BaseResource {
+ /**
+ * Add a file share to a file.
+ *
+ * @param fileId File ID
+ * @param fileBodyPart File to add
+ * @return Response
+ * @throws JSONException
+ */
+ @PUT
+ @Consumes("multipart/form-data")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response add(
+ @FormDataParam("id") String fileId) throws JSONException {
+ if (!authenticate()) {
+ throw new ForbiddenClientException();
+ }
+
+ // Validate input data
+ ValidationUtil.validateRequired(fileId, "id");
+
+ // Get the file
+ // TODO Not implemented
+
+ // Always return ok
+ JSONObject response = new JSONObject();
+ response.put("status", "ok");
+ response.put("id", fileId);
+ return Response.ok().entity(response).build();
+ }
+
+ /**
+ * Deletes a file share.
+ *
+ * @param id File shqre ID
+ * @return Response
+ * @throws JSONException
+ */
+ @DELETE
+ @Path("{id: [a-z0-9\\-]+}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response delete(
+ @PathParam("id") String id) throws JSONException {
+ if (!authenticate()) {
+ throw new ForbiddenClientException();
+ }
+
+ // Get the file shqre
+// FileShareDao fileShareDao = new FileShareDao();
+// FileShare fileShare;
+// try {
+// fileShare = fileShareDao.getFileShare(id);
+// } catch (NoResultException e) {
+// throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id));
+// }
+//
+// // Delete the file share
+// fileShareDao.delete(fileShare.getId());
+
+ // TODO Not implemented
+
+ // Always return ok
+ JSONObject response = new JSONObject();
+ response.put("status", "ok");
+ return Response.ok().entity(response).build();
+ }
+}
diff --git a/docs-web/src/prod/resources/config.properties b/docs-web/src/prod/resources/config.properties
index a7a2e43f..299540e8 100644
--- a/docs-web/src/prod/resources/config.properties
+++ b/docs-web/src/prod/resources/config.properties
@@ -1,3 +1,3 @@
api.current_version=${project.version}
api.min_version=1.0
-db.version=3
\ No newline at end of file
+db.version=4
\ No newline at end of file