Merge branch 'dev'
Change-Id: I8083ab4bdb43a542d6bc5bb764dd7ca00f7a6051
diff --git a/build.gradle b/build.gradle
index 1be97fb..60e39f3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,7 +15,7 @@
description = 'MDM API - Base Model'
group = 'org.eclipse.mdm'
-version = '5.1.0'
+version = '5.2.0M1-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'maven'
diff --git a/src/main/java/org/eclipse/mdm/api/base/file/FileService.java b/src/main/java/org/eclipse/mdm/api/base/file/FileService.java
index b58e225..9a552cc 100644
--- a/src/main/java/org/eclipse/mdm/api/base/file/FileService.java
+++ b/src/main/java/org/eclipse/mdm/api/base/file/FileService.java
@@ -1,5 +1,5 @@
/********************************************************************************
- * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
@@ -88,6 +88,7 @@
void downloadParallel(Entity entity, Path target, Collection<FileLink> fileLinks, ProgressListener progressListener)
throws IOException;
+
/**
* Downloads given {@link FileLink} into given target {@code Path}.
*
@@ -182,5 +183,57 @@
void progress(int bytes, float percent);
}
+
+ /**
+ * Sequential upload of given {@link FileLink}s. Local {@link Path}s linked
+ * multiple times are uploaded only once. The upload progress may be traced with
+ * a progress listener.
+ *
+ * @param entity Used for security checks.
+ * @param fileLinks Collection of {@code FileLink}s to upload.
+ * @param progressListener The progress listener.
+ * @throws IOException Thrown if unable to upload files.
+ */
+ public void uploadSequential(Entity entity, Collection<FileLink> fileLinks, ProgressListener progressListener) throws IOException;
+
+ /**
+ * Parallel upload of given {@link FileLink}s. Local {@link Path}s linked
+ * multiple times are uploaded only once. The upload progress may be traced with
+ * a progress listener.
+ *
+ * @param entity Used for security checks.
+ * @param fileLinks Collection of {@code FileLink}s to upload.
+ * @param progressListener The progress listener.
+ * @throws IOException Thrown if unable to upload files.
+ */
+ public void uploadParallel(Entity entity, Collection<FileLink> fileLinks, ProgressListener progressListener)
+ throws IOException;
+
+ /**
+ * Deletes given {@link FileLink}s form the remote storage.
+ *
+ * @param entity Used for security checks.
+ * @param fileLinks Collection of {@code FileLink}s to delete.
+ */
+ public void delete(Entity entity, Collection<FileLink> fileLinks);
+
+ /**
+ * Deletes given {@link FileLink} form the remote storage.
+ *
+ * @param entity Used for security checks.
+ * @param fileLink The {@code FileLink}s to delete.
+ */
+ public void delete(Entity entity, FileLink fileLink);
+
+
+
+
+
+
+
+
+
+
+
}
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/FileLink.java b/src/main/java/org/eclipse/mdm/api/base/model/FileLink.java
index a2e231a..f558b54 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/FileLink.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/FileLink.java
@@ -1,5 +1,5 @@
/********************************************************************************
- * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation
+ * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
@@ -15,6 +15,7 @@
package org.eclipse.mdm.api.base.model;
import java.io.IOException;
+import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
@@ -40,7 +41,8 @@
private MimeType mimeType;
private String description;
- private Path localPath;
+ private InputStream localStream;
+ private String localFileName;
private long size = -1;
@@ -57,7 +59,7 @@
remotePath = fileLink.remotePath;
mimeType = fileLink.mimeType;
description = fileLink.description;
- localPath = fileLink.localPath;
+ localStream = fileLink.localStream;
size = fileLink.size;
state = fileLink.state;
}
@@ -81,16 +83,12 @@
* @param localPath The local {@link Path}.
* @throws IOException Thrown in case of errors.
*/
- private FileLink(Path localPath) throws IOException {
- this.localPath = localPath;
- String type = Files.probeContentType(localPath);
- mimeType = new MimeType(type == null ? "application/octet-stream" : type);
- size = Files.size(localPath);
- Path fileNamePath = localPath.getFileName();
- if (fileNamePath != null) {
- description = fileNamePath.toString();
- }
-
+ private FileLink(InputStream localStream, String name, long size, MimeType mimeType, String description) throws IOException {
+ this.localStream = localStream;
+ this.mimeType = mimeType == null ? new MimeType("application/octet-stream") : mimeType;
+ this.size = size;
+ this.localFileName = name;
+ this.description = description;
state = State.LOCAL;
}
@@ -120,6 +118,10 @@
* @throws IOException Thrown if unable to access file with given {@code
* Path} .
*/
+ public static FileLink newLocal(InputStream localStream, String name, long size, MimeType mimeType, String description) throws IOException {
+ return new FileLink(localStream, name, size, mimeType, description);
+ }
+
public static FileLink newLocal(Path localPath) throws IOException {
if (Files.isDirectory(localPath)) {
throw new IllegalArgumentException("Local path is a directory.");
@@ -128,8 +130,13 @@
} else if (!Files.isReadable(localPath)) {
throw new IllegalArgumentException("Local path is not readable.");
}
-
- return new FileLink(localPath);
+
+ InputStream localStream = Files.newInputStream(localPath);
+ long size = Files.size(localPath);
+ String name = localPath.getFileName().toString();
+ String mimeType = Files.probeContentType(localPath);
+ MimeType mimeT = mimeType == null ? null : new MimeType(mimeType);
+ return new FileLink(localStream, name, size, mimeT, name);
}
/**
@@ -140,8 +147,9 @@
*/
public String getFileName() {
Path fileNamePath = null;
+ String fileName = null;
if (isLocal()) {
- fileNamePath = getLocalPath().getFileName();
+ fileName = this.localFileName;
} else if (isRemote()) {
try {
// on Windows, Paths.get() cannot handle file urls in the form
@@ -151,13 +159,14 @@
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Unable to decode remote path due to: " + e.getMessage(), e);
}
+
+ if (fileNamePath == null) {
+ throw new IllegalStateException("File name is unknown.");
+ }
+ fileName = fileNamePath.toString();
}
- if (fileNamePath == null) {
- throw new IllegalStateException("File name is unknown.");
- }
-
- return fileNamePath.toString();
+ return fileName;
}
/**
@@ -175,37 +184,37 @@
* @return Returns {@code true} if a local {@code Path} is available.
*/
public boolean isLocal() {
- return localPath != null;
+ return localStream != null;
}
/**
- * Returns the local {@link Path} to the linked file. Calling this method is
+ * Returns the local {@link InputStream} to the linked file. Calling this method is
* only allowed if calling {@link #isLocal()} returns {@code
* true}.
*
* @return The local {@code Path} to the linked file is returned.
*/
- public Path getLocalPath() {
+ public InputStream getLocalStream() {
if (isLocal()) {
- return localPath;
+ return localStream;
}
throw new IllegalStateException("Local path is not available.");
}
/**
- * This method is called by API providers to set the local {@link Path} once the
+ * This method is called by API providers to set the local {@link InputStream} once the
* remote file was downloaded.
*
- * @param localPath The local {@code Path} of the downloaded file.
+ * @param localPath The local {@code InputStream} of the downloaded file.
* @throws IllegalStateException Thrown if this file link is 'LOCAL'.
*/
- public void setLocalPath(Path localPath) {
+ public void setLocalStream(InputStream localStream) {
if (State.LOCAL == state) {
throw new IllegalStateException("It is not allowed to replace an existing local path.");
}
- this.localPath = localPath;
+ this.localStream = localStream;
}
/**
@@ -301,7 +310,7 @@
if (!isLocal()) {
return "".hashCode();
}
- return getLocalPath().hashCode();
+ return getLocalStream().hashCode();
}
if (!isRemote()) {
return "".hashCode();
@@ -321,7 +330,7 @@
if (!isLocal()) {
return !other.isLocal();
}
- return getLocalPath().equals(other.getLocalPath());
+ return getLocalStream().equals(other.getLocalStream());
}
if (!isRemote()) {
return !other.isRemote();
@@ -345,7 +354,7 @@
}
if (isLocal()) {
- sb.append(", LocalPath = ").append(getLocalPath().toAbsolutePath());
+ sb.append(", LocalPath = ").append(getLocalStream());
}
if (isRemote()) {
@@ -393,7 +402,7 @@
* {@code Path} which are equal.
*/
private static boolean isLocalPathEqual(FileLink o1, FileLink o2) {
- return o1.isLocal() && o2.isLocal() && o1.getLocalPath().equals(o2.getLocalPath());
+ return o1.isLocal() && o2.isLocal() && o1.getLocalStream().equals(o2.getLocalStream());
}
/**