package uk.ac.ic.wlgitbridge.data.model; import com.ning.http.client.AsyncCompletionHandler; import com.ning.http.client.HttpResponseBodyPart; import com.ning.http.client.Response; import org.eclipse.jgit.lib.Repository; import uk.ac.ic.wlgitbridge.data.filestore.RawFile; import uk.ac.ic.wlgitbridge.data.filestore.RepositoryFile; import uk.ac.ic.wlgitbridge.data.model.db.PersistentStore; import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker; import uk.ac.ic.wlgitbridge.snapshot.base.Request; import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException; import uk.ac.ic.wlgitbridge.snapshot.push.exception.SnapshotPostException; import uk.ac.ic.wlgitbridge.util.Log; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Map; import java.util.concurrent.ExecutionException; /** * Created by Winston on 21/02/15. */ public class ResourceFetcher { private final PersistentStore persistentStore; public ResourceFetcher(PersistentStore persistentStore) { this.persistentStore = persistentStore; } public RawFile get(String projectName, String url, String newPath, Map<String, RawFile> fileTable, Map<String, byte[]> fetchedUrls) throws IOException, SnapshotPostException { String path = persistentStore.getPathForURLInProject(projectName, url); byte[] contents; if (path == null) { path = newPath; contents = fetch(projectName, url, path); fetchedUrls.put(url, contents); } else { Log.info("Found (" + projectName + "): " + url); Log.info("At (" + projectName + "): " + path); contents = fetchedUrls.get(url); if (contents == null) { RawFile rawFile = fileTable.get(path); if (rawFile == null) { Log.warn( "File " + path + " was not in the current commit, or the git tree, yet path was not null. " + "File url is: " + url ); contents = fetch(projectName, url, path); } else { contents = rawFile.getContents(); } } } return new RepositoryFile(newPath, contents); } private byte[] fetch(String projectName, final String url, String path) throws FailedConnectionException { byte[] contents; Log.info("GET -> " + url); try { contents = Request.httpClient.prepareGet(url).execute(new AsyncCompletionHandler<byte[]>() { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); @Override public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception { bytes.write(bodyPart.getBodyPartBytes()); return STATE.CONTINUE; } @Override public byte[] onCompleted(Response response) throws Exception { byte[] data = bytes.toByteArray(); bytes.close(); Log.info(response.getStatusCode() + " " + response.getStatusText() + " (" + data.length + "B) -> " + url); return data; } }).get(); } catch (InterruptedException e) { Log.warn( "Interrupted when fetching project: " + projectName + ", url: " + url + ", path: " + path, e ); throw new FailedConnectionException(); } catch (ExecutionException e) { Log.warn( "ExecutionException when fetching project: " + projectName + ", url: " + url + ", path: " + path, e ); throw new FailedConnectionException(); } persistentStore.addURLIndexForProject(projectName, url, path); return contents; } }