1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.lfs.server.fs;
11
12 import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION;
13
14 import java.io.IOException;
15 import java.nio.channels.FileChannel;
16 import java.nio.channels.ReadableByteChannel;
17 import java.nio.file.Files;
18 import java.nio.file.Path;
19 import java.nio.file.StandardOpenOption;
20 import java.util.Collections;
21
22 import org.eclipse.jgit.annotations.Nullable;
23 import org.eclipse.jgit.lfs.internal.AtomicObjectOutputStream;
24 import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
25 import org.eclipse.jgit.lfs.lib.Constants;
26 import org.eclipse.jgit.lfs.server.LargeFileRepository;
27 import org.eclipse.jgit.lfs.server.Response;
28 import org.eclipse.jgit.lfs.server.Response.Action;
29
30
31
32
33
34
35 public class FileLfsRepository implements LargeFileRepository {
36
37 private String url;
38 private final Path dir;
39
40
41
42
43
44
45
46
47
48
49 public FileLfsRepository(String url, Path dir) throws IOException {
50 this.url = url;
51 this.dir = dir;
52 Files.createDirectories(dir);
53 }
54
55
56 @Override
57 public Response.Action getDownloadAction(AnyLongObjectId id) {
58 return getAction(id);
59 }
60
61
62 @Override
63 public Action getUploadAction(AnyLongObjectId id, long size) {
64 return getAction(id);
65 }
66
67
68 @Override
69 @Nullable
70 public Action getVerifyAction(AnyLongObjectId id) {
71 return null;
72 }
73
74
75 @Override
76 public long getSize(AnyLongObjectId id) throws IOException {
77 Path p = getPath(id);
78 if (Files.exists(p)) {
79 return Files.size(p);
80 }
81 return -1;
82 }
83
84
85
86
87
88
89 public Path getDir() {
90 return dir;
91 }
92
93
94
95
96
97
98
99
100 protected Path getPath(AnyLongObjectId id) {
101 StringBuilder s = new StringBuilder(
102 Constants.LONG_OBJECT_ID_STRING_LENGTH + 6);
103 s.append(toHexCharArray(id.getFirstByte())).append('/');
104 s.append(toHexCharArray(id.getSecondByte())).append('/');
105 s.append(id.name());
106 return dir.resolve(s.toString());
107 }
108
109 private Response.Action getAction(AnyLongObjectId id) {
110 Response.Action a = new Response.Action();
111 a.href = url + id.getName();
112 a.header = Collections.singletonMap(HDR_AUTHORIZATION, "not:required");
113 return a;
114 }
115
116 ReadableByteChannel getReadChannel(AnyLongObjectId id)
117 throws IOException {
118 return FileChannel.open(getPath(id), StandardOpenOption.READ);
119 }
120
121 AtomicObjectOutputStream getOutputStream(AnyLongObjectId id)
122 throws IOException {
123 Path path = getPath(id);
124 Path parent = path.getParent();
125 if (parent != null) {
126 Files.createDirectories(parent);
127 }
128 return new AtomicObjectOutputStream(path, id);
129 }
130
131 private static char[] toHexCharArray(int b) {
132 final char[] dst = new char[2];
133 formatHexChar(dst, 0, b);
134 return dst;
135 }
136
137 private static final char[] hexchar = { '0', '1', '2', '3', '4', '5', '6',
138 '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
139
140 private static void formatHexChar(char[] dst, int p, int b) {
141 int o = p + 1;
142 while (o >= p && b != 0) {
143 dst[o--] = hexchar[b & 0xf];
144 b >>>= 4;
145 }
146 while (o >= p)
147 dst[o--] = '0';
148 }
149
150
151
152
153
154 public String getUrl() {
155 return url;
156 }
157
158
159
160
161
162
163 public void setUrl(String url) {
164 this.url = url;
165 }
166 }