xref: /JGit/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java (revision 5c5f7c6b146b24f2bd4afae1902df85ad6e57ea3)
1 /*
2  * Copyright (C) 2015, Sasa Zivkov <sasa.zivkov@sap.com> and others
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Distribution License v. 1.0 which is available at
6  * https://www.eclipse.org/org/documents/edl-v10.php.
7  *
8  * SPDX-License-Identifier: BSD-3-Clause
9  */
10 
11 package org.eclipse.jgit.lfs.server;
12 
13 import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
14 import static org.eclipse.jgit.lfs.lib.Constants.DOWNLOAD;
15 import static org.eclipse.jgit.lfs.lib.Constants.UPLOAD;
16 import static org.eclipse.jgit.lfs.lib.Constants.VERIFY;
17 
18 import java.io.IOException;
19 import java.text.MessageFormat;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 
24 import org.eclipse.jgit.lfs.lib.LongObjectId;
25 import org.eclipse.jgit.lfs.server.Response.Action;
26 import org.eclipse.jgit.lfs.server.Response.Body;
27 import org.eclipse.jgit.lfs.server.internal.LfsServerText;
28 
29 abstract class TransferHandler {
30 
forOperation(String operation, LargeFileRepository repository, List<LfsObject> objects)31 	static TransferHandler forOperation(String operation,
32 			LargeFileRepository repository, List<LfsObject> objects) {
33 		switch (operation) {
34 		case UPLOAD:
35 			return new Upload(repository, objects);
36 		case DOWNLOAD:
37 			return new Download(repository, objects);
38 		case VERIFY:
39 		default:
40 			throw new UnsupportedOperationException(MessageFormat.format(
41 					LfsServerText.get().unsupportedOperation, operation));
42 		}
43 	}
44 
45 	private static class Upload extends TransferHandler {
Upload(LargeFileRepository repository, List<LfsObject> objects)46 		Upload(LargeFileRepository repository,
47 				List<LfsObject> objects) {
48 			super(repository, objects);
49 		}
50 
51 		@Override
process()52 		Body process() throws IOException {
53 			Response.Body body = new Response.Body();
54 			if (!objects.isEmpty()) {
55 				body.objects = new ArrayList<>();
56 				for (LfsObject o : objects) {
57 					addObjectInfo(body, o);
58 				}
59 			}
60 			return body;
61 		}
62 
addObjectInfo(Response.Body body, LfsObject o)63 		private void addObjectInfo(Response.Body body, LfsObject o)
64 				throws IOException {
65 			Response.ObjectInfo info = new Response.ObjectInfo();
66 			body.objects.add(info);
67 			info.oid = o.oid;
68 			info.size = o.size;
69 
70 			LongObjectId oid = LongObjectId.fromString(o.oid);
71 			if (repository.getSize(oid) == -1) {
72 				info.actions = new HashMap<>();
73 				info.actions.put(UPLOAD,
74 						repository.getUploadAction(oid, o.size));
75 				Action verify = repository.getVerifyAction(oid);
76 				if (verify != null) {
77 					info.actions.put(VERIFY, verify);
78 				}
79 			}
80 		}
81 	}
82 
83 	private static class Download extends TransferHandler {
Download(LargeFileRepository repository, List<LfsObject> objects)84 		Download(LargeFileRepository repository,
85 				List<LfsObject> objects) {
86 			super(repository, objects);
87 		}
88 
89 		@Override
process()90 		Body process() throws IOException {
91 			Response.Body body = new Response.Body();
92 			if (!objects.isEmpty()) {
93 				body.objects = new ArrayList<>();
94 				for (LfsObject o : objects) {
95 					addObjectInfo(body, o);
96 				}
97 			}
98 			return body;
99 		}
100 
addObjectInfo(Response.Body body, LfsObject o)101 		private void addObjectInfo(Response.Body body, LfsObject o)
102 				throws IOException {
103 			Response.ObjectInfo info = new Response.ObjectInfo();
104 			body.objects.add(info);
105 			info.oid = o.oid;
106 			info.size = o.size;
107 
108 			LongObjectId oid = LongObjectId.fromString(o.oid);
109 			if (repository.getSize(oid) >= 0) {
110 				info.actions = new HashMap<>();
111 				info.actions.put(DOWNLOAD,
112 						repository.getDownloadAction(oid));
113 			} else {
114 				info.error = new Response.Error();
115 				info.error.code = SC_NOT_FOUND;
116 				info.error.message = MessageFormat.format(
117 						LfsServerText.get().objectNotFound,
118 						oid.getName());
119 			}
120 		}
121 	}
122 
123 	final LargeFileRepository repository;
124 
125 	final List<LfsObject> objects;
126 
TransferHandler(LargeFileRepository repository, List<LfsObject> objects)127 	TransferHandler(LargeFileRepository repository,
128 			List<LfsObject> objects) {
129 		this.repository = repository;
130 		this.objects = objects;
131 	}
132 
process()133 	abstract Response.Body process() throws IOException;
134 }
135