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