Add 'sdk/java-v2/' from commit '55f103e336ca9fb8bf1720d2ef4ee8dd4e221118'
[arvados.git] / sdk / java-v2 / src / main / java / org / arvados / client / logic / collection / ManifestDecoder.java
1 /*
2  * Copyright (C) The Arvados Authors. All rights reserved.
3  *
4  * SPDX-License-Identifier: AGPL-3.0 OR Apache-2.0
5  *
6  */
7
8 package org.arvados.client.logic.collection;
9
10 import org.arvados.client.common.Characters;
11 import org.arvados.client.exception.ArvadosClientException;
12 import org.arvados.client.logic.keep.KeepLocator;
13
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.LinkedList;
17 import java.util.List;
18 import java.util.Objects;
19
20 import static java.util.stream.Collectors.toList;
21 import static org.arvados.client.common.Patterns.FILE_TOKEN_PATTERN;
22 import static org.arvados.client.common.Patterns.LOCATOR_PATTERN;
23
24 public class ManifestDecoder {
25
26     public List<ManifestStream> decode(String manifestText) {
27
28         if (manifestText == null || manifestText.isEmpty()) {
29             throw new ArvadosClientException("Manifest text cannot be empty.");
30         }
31
32         List<String> manifestStreams = new ArrayList<>(Arrays.asList(manifestText.split("\\n")));
33         if (!manifestStreams.get(0).startsWith(". ")) {
34             throw new ArvadosClientException("Invalid first path component (expecting \".\")");
35         }
36
37         return manifestStreams.stream()
38                 .map(this::decodeSingleManifestStream)
39                 .collect(toList());
40     }
41
42     private ManifestStream decodeSingleManifestStream(String manifestStream) {
43         Objects.requireNonNull(manifestStream, "Manifest stream cannot be empty.");
44
45         LinkedList<String> manifestPieces = new LinkedList<>(Arrays.asList(manifestStream.split("\\s+")));
46         String streamName = manifestPieces.poll();
47         String path = ".".equals(streamName) ? "" : streamName.substring(2).concat(Characters.SLASH);
48
49         List<KeepLocator> keepLocators = manifestPieces
50                 .stream()
51                 .filter(p -> p.matches(LOCATOR_PATTERN))
52                 .map(this::getKeepLocator)
53                 .collect(toList());
54
55
56         List<FileToken> fileTokens = manifestPieces.stream()
57                 .skip(keepLocators.size())
58                 .filter(p -> p.matches(FILE_TOKEN_PATTERN))
59                 .map(p -> new FileToken(p, path))
60                 .collect(toList());
61
62         return new ManifestStream(streamName, keepLocators, fileTokens);
63
64     }
65
66     private KeepLocator getKeepLocator(String locatorString ) {
67         try {
68             return new KeepLocator(locatorString);
69         } catch (Exception e) {
70             throw new RuntimeException(e);
71         }
72     }
73
74 }