View Javadoc
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  
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 {
46  		Upload(LargeFileRepository repository,
47  				List<LfsObject> objects) {
48  			super(repository, objects);
49  		}
50  
51  		@Override
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  
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 {
84  		Download(LargeFileRepository repository,
85  				List<LfsObject> objects) {
86  			super(repository, objects);
87  		}
88  
89  		@Override
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 
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 
127 	TransferHandler(LargeFileRepository repository,
128 			List<LfsObject> objects) {
129 		this.repository = repository;
130 		this.objects = objects;
131 	}
132 
133 	abstract Response.Body process() throws IOException;
134 }