diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/File.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/File.java
index 64682bc6..36143622 100644
--- a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/File.java
+++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/File.java
@@ -10,6 +10,8 @@ import javax.persistence.Table;
import javax.persistence.Transient;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+import com.sismics.util.mime.MimeTypeUtil;
/**
* File entity.
@@ -38,12 +40,18 @@ public class File implements Loggable {
@Column(name = "FIL_IDUSER_C", length = 36, nullable = false)
private String userId;
+ /**
+ * Name.
+ */
+ @Column(name = "FIL_NAME_C", length = 200)
+ private String name;
+
/**
* MIME type.
*/
@Column(name = "FIL_MIMETYPE_C", length = 100)
private String mimeType;
-
+
/**
* OCR-ized content.
*/
@@ -92,6 +100,15 @@ public class File implements Loggable {
this.documentId = documentId;
}
+ public String getName() {
+ return name;
+ }
+
+ public File setName(String name) {
+ this.name = name;
+ return this;
+ }
+
public String getMimeType() {
return mimeType;
}
@@ -153,6 +170,7 @@ public class File implements Loggable {
public String toString() {
return MoreObjects.toStringHelper(this)
.add("id", id)
+ .add("name", name)
.toString();
}
@@ -160,4 +178,17 @@ public class File implements Loggable {
public String toMessage() {
return documentId;
}
+
+ /**
+ * Build the full file name.
+ *
+ * @param def Default name if the file doesn't have one.
+ * @return File name
+ */
+ public String getFullName(String def) {
+ if (Strings.isNullOrEmpty(name)) {
+ return def + "." + MimeTypeUtil.getFileExtension(mimeType);
+ }
+ return name;
+ }
}
diff --git a/docs-core/src/main/java/com/sismics/util/mime/MimeType.java b/docs-core/src/main/java/com/sismics/util/mime/MimeType.java
index b844aced..8e77180a 100644
--- a/docs-core/src/main/java/com/sismics/util/mime/MimeType.java
+++ b/docs-core/src/main/java/com/sismics/util/mime/MimeType.java
@@ -20,5 +20,9 @@ public class MimeType {
public static final String OFFICE_DOCUMENT = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
+ public static final String TEXT_PLAIN = "text/plain";
+
+ public static final String TEXT_CSV = "text/csv";
+
public static final String DEFAULT = "application/octet-stream";
}
diff --git a/docs-core/src/main/java/com/sismics/util/mime/MimeTypeUtil.java b/docs-core/src/main/java/com/sismics/util/mime/MimeTypeUtil.java
index c784de77..124d03ab 100644
--- a/docs-core/src/main/java/com/sismics/util/mime/MimeTypeUtil.java
+++ b/docs-core/src/main/java/com/sismics/util/mime/MimeTypeUtil.java
@@ -21,32 +21,30 @@ public class MimeTypeUtil {
* Try to guess the MIME type of a file by its magic number (header).
*
* @param is Stream to inspect
+ * @param name File name
* @return MIME type
- * @throws IOException
+ * @throws IOException e
*/
- public static String guessMimeType(InputStream is) throws IOException {
+ public static String guessMimeType(InputStream is, String name) throws IOException {
byte[] headerBytes = new byte[64];
is.mark(headerBytes.length);
- int readCount = is.read(headerBytes);
+ is.read(headerBytes);
is.reset();
-
- if (readCount <= 0) {
- throw new IOException("Cannot read input file");
- }
-
- return guessMimeType(headerBytes);
+ return guessMimeType(headerBytes, name);
}
/**
* Try to guess the MIME type of a file by its magic number (header).
*
* @param headerBytes File header (first bytes)
+ * @param name File name
* @return MIME type
- * @throws UnsupportedEncodingException
+ * @throws UnsupportedEncodingException e
*/
- public static String guessMimeType(byte[] headerBytes) throws UnsupportedEncodingException {
+ public static String guessMimeType(byte[] headerBytes, String name) throws UnsupportedEncodingException {
String header = new String(headerBytes, "US-ASCII");
-
+
+ // Detect by header bytes
if (header.startsWith("PK")) {
return MimeType.APPLICATION_ZIP;
} else if (header.startsWith("GIF87a") || header.startsWith("GIF89a")) {
@@ -59,7 +57,16 @@ public class MimeTypeUtil {
} else if (headerBytes[0] == ((byte) 0x25) && headerBytes[1] == ((byte) 0x50) && headerBytes[2] == ((byte) 0x44) && headerBytes[3] == ((byte) 0x46)) {
return MimeType.APPLICATION_PDF;
}
-
+
+ // Detect by file extension
+ if (name != null) {
+ if (name.endsWith(".txt")) {
+ return MimeType.TEXT_PLAIN;
+ } else if (name.endsWith(".csv")) {
+ return MimeType.TEXT_CSV;
+ }
+ }
+
return MimeType.DEFAULT;
}
@@ -86,7 +93,7 @@ public class MimeTypeUtil {
case MimeType.OFFICE_DOCUMENT:
return "docx";
default:
- return null;
+ return "bin";
}
}
diff --git a/docs-core/src/main/resources/config.properties b/docs-core/src/main/resources/config.properties
index 592e6288..1d7a2e79 100644
--- a/docs-core/src/main/resources/config.properties
+++ b/docs-core/src/main/resources/config.properties
@@ -1 +1 @@
-db.version=10
\ No newline at end of file
+db.version=11
\ No newline at end of file
diff --git a/docs-core/src/main/resources/db/update/dbupdate-011-0.sql b/docs-core/src/main/resources/db/update/dbupdate-011-0.sql
new file mode 100644
index 00000000..4c40f7e8
--- /dev/null
+++ b/docs-core/src/main/resources/db/update/dbupdate-011-0.sql
@@ -0,0 +1,2 @@
+alter table T_FILE add column FIL_NAME_C varchar(200);
+update T_CONFIG set CFG_VALUE_C = '11' where CFG_ID_C = 'DB_VERSION';
diff --git a/docs-web/src/dev/resources/config.properties b/docs-web/src/dev/resources/config.properties
index f935e8fa..25d63162 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=10
\ No newline at end of file
+db.version=11
\ 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 8734fea7..eb872a75 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
@@ -124,9 +124,11 @@ public class FileResource extends BaseResource {
InputStream fileInputStream = new ByteArrayInputStream(fileData);
// Validate mime type
+ String name = fileBodyPart.getContentDisposition() != null ?
+ fileBodyPart.getContentDisposition().getFileName() : null;
String mimeType;
try {
- mimeType = MimeTypeUtil.guessMimeType(fileInputStream);
+ mimeType = MimeTypeUtil.guessMimeType(fileInputStream, name);
} catch (IOException e) {
throw new ServerException("ErrorGuessMime", "Error guessing mime type", e);
}
@@ -150,6 +152,7 @@ public class FileResource extends BaseResource {
File file = new File();
file.setOrder(order);
file.setDocumentId(documentId);
+ file.setName(name);
file.setMimeType(mimeType);
file.setUserId(principal.getId());
String fileId = fileDao.create(file, principal.getId());
@@ -338,6 +341,7 @@ public class FileResource extends BaseResource {
* @apiSuccess {Object[]} files List of files
* @apiSuccess {String} files.id ID
* @apiSuccess {String} files.mimetype MIME type
+ * @apiSuccess {String} files.name File name
* @apiSuccess {String} files.document_id Document ID
* @apiSuccess {String} files.create_date Create date (timestamp)
* @apiSuccess {String} files.size File size (in bytes)
@@ -376,6 +380,7 @@ public class FileResource extends BaseResource {
try {
files.add(Json.createObjectBuilder()
.add("id", fileDb.getId())
+ .add("name", JsonUtil.nullable(fileDb.getName()))
.add("mimetype", fileDb.getMimeType())
.add("document_id", JsonUtil.nullable(fileDb.getDocumentId()))
.add("create_date", fileDb.getCreateDate().getTime())
@@ -579,6 +584,7 @@ public class FileResource extends BaseResource {
}
return Response.ok(stream)
+ .header("Content-Disposition", "inline; filename=" + file.getFullName("data"))
.header("Content-Type", mimeType)
.header("Expires", new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z").format(new Date().getTime() + 3600000 * 24))
.build();
@@ -636,7 +642,7 @@ public class FileResource extends BaseResource {
// Files are encrypted by the creator of them
User user = userDao.getById(file.getUserId());
try (InputStream decryptedStream = EncryptionUtil.decryptInputStream(fileInputStream, user.getPrivateKey())) {
- ZipEntry zipEntry = new ZipEntry(index + "." + MimeTypeUtil.getFileExtension(file.getMimeType()));
+ ZipEntry zipEntry = new ZipEntry(file.getFullName(Integer.toString(index)));
zipOutputStream.putNextEntry(zipEntry);
ByteStreams.copy(decryptedStream, zipOutputStream);
zipOutputStream.closeEntry();
diff --git a/docs-web/src/main/webapp/src/partial/docs/document.view.content.html b/docs-web/src/main/webapp/src/partial/docs/document.view.content.html
index cc58fdee..c3b0ca74 100644
--- a/docs-web/src/main/webapp/src/partial/docs/document.view.content.html
+++ b/docs-web/src/main/webapp/src/partial/docs/document.view.content.html
@@ -46,6 +46,7 @@
+