| 35 | import org.jetbrains.annotations.TestOnly; |
| 36 | |
| 37 | public class VolumeDefinitions implements Mutable { |
| 38 | private static final char SEPARATOR = ','; |
| 39 | private final LowerCaseCharSequenceObjHashMap<String> aliasToVolumeRoot = new LowerCaseCharSequenceObjHashMap<>(4); |
| 40 | private int hi; |
| 41 | private int limit; |
| 42 | private int lo; |
| 43 | |
| 44 | @TestOnly |
| 45 | @Override |
| 46 | public void clear() { |
| 47 | aliasToVolumeRoot.clear(); |
| 48 | lo = hi = limit = 0; |
| 49 | } |
| 50 | |
| 51 | public void forEach(LowerCaseCharSequenceObjHashMap.CharSequenceObjConsumer<String> action) { |
| 52 | aliasToVolumeRoot.forEach(action); |
| 53 | } |
| 54 | |
| 55 | public VolumeDefinitions of(@Nullable CharSequence definitions, @NotNull Path path, @NotNull String root) throws ServerConfigurationException { |
| 56 | if (definitions != null) { |
| 57 | // 'any-case-alias' -> 'absolute path to volume' (quotes are optional) |
| 58 | aliasToVolumeRoot.clear(); |
| 59 | limit = definitions.length(); |
| 60 | lo = 0; |
| 61 | int separatorCount = 0; |
| 62 | String alias = null; |
| 63 | for (int i = 0; i < limit; i++) { |
| 64 | char c = definitions.charAt(i); |
| 65 | if (c == '-' && i + 1 < limit && definitions.charAt(i + 1) == '>') { // found arrow |
| 66 | if (alias != null) { |
| 67 | throw new ServerConfigurationException("invalid syntax, missing volume path at offset " + lo); |
| 68 | } |
| 69 | alias = Chars.toString(popToken(definitions, i, false)); |
| 70 | lo = ++i + 1; // move over '>' |
| 71 | } else if (SEPARATOR == c) { |
| 72 | if (alias == null) { |
| 73 | throw new ServerConfigurationException("invalid syntax, missing alias at offset " + lo); |
| 74 | } |
| 75 | addVolumeDefinition(alias, popToken(definitions, i, false), path, root); |
| 76 | alias = null; |
| 77 | lo = i + 1; |
| 78 | separatorCount++; |
| 79 | } |
| 80 | } |
| 81 | finishVolumeDefinitions(alias, popToken(definitions, limit, true), path, root, separatorCount); |
| 82 | } |
| 83 | return this; |
| 84 | } |
| 85 | |
| 86 | public @Nullable CharSequence resolveAlias(@NotNull CharSequence alias) { |
| 87 | return aliasToVolumeRoot.get(alias); |
| 88 | } |
| 89 | |
| 90 | public @Nullable CharSequence resolvePath(@NotNull CharSequence path) { |
| 91 | for (int i = 0, n = aliasToVolumeRoot.keys().size(); i < n; i++) { |
| 92 | final CharSequence candidateAlias = aliasToVolumeRoot.keys().get(i); |
| 93 | final CharSequence candidatePath = aliasToVolumeRoot.get(candidateAlias); |
| 94 | if (Chars.equals(candidatePath, path)) { |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…