package org.diretto.api.client.main.storage.upload; import java.io.File; import java.io.InputStream; import java.net.URL; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.commons.configuration.XMLConfiguration; import org.apache.http.auth.AuthScope; import org.apache.http.entity.FileEntity; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.diretto.api.client.base.annotations.InvocationLimited; import org.diretto.api.client.base.data.UploadInfo; import org.diretto.api.client.main.storage.StorageService; import org.diretto.api.client.main.storage.StorageServiceImpl; import org.diretto.api.client.main.storage.base.BasicAccessAuthenticationInterceptor; import org.diretto.api.client.session.UserSession; import org.diretto.api.client.user.UserFactory; import org.diretto.api.client.util.InvocationUtils; import org.restlet.Client; /** * The {@code UploadManager} is responsible for the basic upload aspects. * * @author Tobias Schlecht */ public final class UploadManager { private final URL serviceURL; private final Client restletClient; private final ExecutorService executorService; /** * The constructor is {@code private} to have strict control what instances * exist at any time. Instead of the constructor the {@code public} * <i>static factory method</i> * {@link #getInstance(XMLConfiguration, URL, Client)} returns the instances * of the class. * * @param xmlConfiguration The {@code XMLConfiguration} object (of the * {@code StorageService}) * @param serviceURL The service {@code URL} * @param restletClient The <i>Restlet</i> {@code Client} */ private UploadManager(XMLConfiguration xmlConfiguration, URL serviceURL, Client restletClient) { this.serviceURL = serviceURL; this.restletClient = restletClient; executorService = Executors.newFixedThreadPool(xmlConfiguration.getInt("upload/max-parallel-uploads")); } /** * Returns an {@link UploadManager} instance. * * @param xmlConfiguration The {@code XMLConfiguration} object (of the * {@code StorageService}) * @param serviceURL The service {@code URL} * @param restletClient The <i>Restlet</i> {@code Client} * @return A {@code UploadManager} instance */ @InvocationLimited(legitimateInvocationClasses = {StorageServiceImpl.class}) public static synchronized UploadManager getInstance(XMLConfiguration xmlConfiguration, URL serviceURL, Client restletClient) { String warningMessage = "The method invocation \"" + UploadManager.class.getCanonicalName() + ".getInstance(XMLConfiguration, URL, Client)\" is not intended for this usage. Use the \"" + StorageService.class.getCanonicalName() + "\" for the upload functionalities."; InvocationUtils.checkMethodInvocation(warningMessage, "getInstance", XMLConfiguration.class, URL.class, Client.class); return new UploadManager(xmlConfiguration, serviceURL, restletClient); } /** * Returns the service {@link URL}. * * @return The service {@code URL} */ URL getServiceURL() { return serviceURL; } /** * Returns an <i>Apache</i> {@link DefaultHttpClient} for the given * {@link UserSession}. * * @return An <i>Apache</i> {@code DefaultHttpClient} for the given * {@code UserSession}. */ DefaultHttpClient getHttpClient(UserSession userSession) { DefaultHttpClient httpClient = new DefaultHttpClient(); UserFactory.setCredentials(userSession.getUser(), new AuthScope(serviceURL.getHost(), serviceURL.getPort()), httpClient.getCredentialsProvider()); httpClient.addRequestInterceptor(new BasicAccessAuthenticationInterceptor(), 0); return httpClient; } /** * Returns the <i>Restlet</i> {@link Client}. * * @return The <i>Restlet</i> {@code Client} */ Client getRestletClient() { return restletClient; } /** * Finishes the given {@code UploadProcess} ({@link UploadProcessImpl}). * * @param uploadProcess The {@code UploadProcess} to be finished */ void finish(UploadProcessImpl uploadProcess) { uploadProcess.getHttpClient().getConnectionManager().shutdown(); } /** * @see StorageServiceImpl#createUploadProcess(UserSession, UploadInfo, * File) */ public UploadProcess createUploadProcess(UserSession userSession, UploadInfo uploadInfo, File file) { FileEntity fileEntity = new FileEntity(file, uploadInfo.getPlatformMediaType().getID()); fileEntity.setChunked(false); return new UploadProcessImpl(this, userSession, uploadInfo, new UploadHttpEntity(fileEntity)); } /** * @see StorageServiceImpl#createUploadProcess(UserSession, UploadInfo, * InputStream) */ public UploadProcess createUploadProcess(UserSession userSession, UploadInfo uploadInfo, InputStream inputStream) { InputStreamEntity inputStreamEntity = new InputStreamEntity(inputStream, uploadInfo.getFileSize()); inputStreamEntity.setContentType(uploadInfo.getPlatformMediaType().getID()); inputStreamEntity.setChunked(false); return new UploadProcessImpl(this, userSession, uploadInfo, new UploadHttpEntity(inputStreamEntity)); } /** * @see StorageServiceImpl#executeUploadProcess(UploadProcess) */ public UploadReport executeUploadProcess(UploadProcess uploadProcess) { executorService.execute((UploadProcessImpl) uploadProcess); UploadReport uploadReport = null; try { uploadReport = ((UploadProcessImpl) uploadProcess).get(); } catch(InterruptedException e) { e.printStackTrace(); } catch(ExecutionException e) { e.printStackTrace(); } return uploadReport; } }